프로그래밍 초식 : 똑띠한 UI, 바보 서버 NO NO

Donghun Seol·2023년 4월 25일
0

프로그래밍 초식

목록 보기
6/13

레퍼런스

요구사항과 잘못 구현한 코드

새 매니저로 변경하고, 이전 매니저에서 새 매니저로 바뀐 내역을 남겨야 한다.
퇴사하는 이전 매니저는 퇴직금을 수령한다.

nest.js 기준으로 아래와 같이 작성할 수 있다.

// 클라이언트
fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type':'application/json'
  },
  body: JSON.stringify(
    {
      areaId: aid,
      oldManagerId: mgrId,
      newManagerId: selectedId
    }
  )
})
// 서버 

// manager.controller.ts
@POST('/manager')
changeManager(@Body() changeManagerDto: ChangeManagerDto) {
  return this.managerService.changeManager(data)
}

// manager.service.ts
changeManger(data) { // '왕' 파라미터가 사용됐다. 예시이므로 편의상 이렇게 두자..
  const manager = await this.managerRepository.findOne({where:{areaId : data.areaId}});
  manager.currentManager = data.newManagerId;
  manager.oldManager = data.oldManagerId;
  // 해고된 예전 매니저에겐 퇴직금 지급
  await this.payDischargeAllowance(manager.oldManager);
  await this.managerRepository.save(manager);
  return manager;
}

클라이언트에서 보낸 데이터를 무지성으로 믿고, 비즈니스 로직에 그대로 활용하는 위험한 코드다.

발생가능한 문제

클라이언트가 보낸 금액을 그대로 서버가 받아서 사용한 코드가 있었다. 당시 사용자가 클라이언트에서 0원을 파라미터로 보내서 0원에 상품을 구매한 사례 발생. 대형사고!!

아래의 예시에선 oldManager에게 퇴직금을 지급하는 로직이 들어간다고 가정해보자.
클라이언트에서 악의적으로 oldManager를 바꿔 전송하면 엉뚱한 사람한테 퇴직금이 지급되는 문제 발생.

그러니깐, UI에서 보내온 데이터를 절대로 전부 다 믿으면 안된다. 최대한 데이터를 직접 조회해서 사용해야 하고 중요한 데이터일 경우에는 더더욱 그렇다.

아래와 같이 oldManagerId를 서버에서 DB로부터 직접 조회해 사용한다면 이런 문제를 방지할 수 있다.

// manager.service.ts
changeManger(data) {
  const manager = await this.managerRepository.findOne({where:{areaId : data.areaId}});
  
  // DB에서 가지고 온 정보로 oldManager를 업데이트 가능하므로 그렇게 한다.
  manager.oldManager = manager.currentManager;
  manager.currentManager = data.newManagerId;
  
  // 해고된 예전 매니저에겐 퇴직금 지급 (클라이언트에서 조작할 수 없다.)
  await this.payDischargeAllowance(manager.oldManager);
  await this.managerRepository.save(manager);
  return manager;
}

주요 로직은 서버가 검증 및 구현해야한다.

주요 로직이란 값 검증, 계산, 논리적인 상태 등을 의미한다.
(물론 클라이언트도 검증할 수 있지만, 서버측에서 항상 다시 검증해야된다.)

클라이언트에서 어떤 (잘못된, 악의적인)데이터가 들어오더라도 서버와 DB, 비즈니스 로직의 계산 결과는 유효하고 정당해야한다. 서버가 책임지고 데이터 무결성을 보장해야한다. UI에 의존하지 말자.

profile
I'm going from failure to failure without losing enthusiasm

1개의 댓글

comment-user-thumbnail
2023년 5월 13일

sample mocking comment for api test

답글 달기