[TIL #67] 최종프로젝트 #16 사용자 피드백(JS 수정 공격)

안떽왕·2023년 6월 29일
0

Today I Learned

목록 보기
69/76

오늘도 피드백을 받아 수정하는 시간을 가졌습니다. 오늘은 좀 독특한 피드백이 왔는데 XSS공격을 받아 들어가서는 안될 값이 들어갔습니다.

JS코드 공격

프론트엔드 함수부분에 음수인 숫자는 들어가지 못하도록 예외처리를 해놓은 항목이 있었는데 JS를 수정해서 해당항목을 지워버리고 음수의 값을 넣어 저장을 하니 저장이 되더군요..

백엔드에서도 예외처리가 이루어졌다면 막을 수 있는 현상이었으나 프론트에서 막았다고 너무 안일했던 것 같습니다. 해당 피드백을 받고 바로 코드를 수정했습니다.

우선 프론트에서 막을 수 있는 최선을 하고 백엔드를 수정하는 마음을 먹었기에 먼저 html태그부터 시작했습니다.

<input type="text"/>

기존에 input타입이 text였는데 아예 형식을 정해주자고 생각해 타입과 min을 추가했습니다.

<input type="number" min="1"/>

다음은 js의 예외처리입니다.

    const durationValue = parseInt(duration);
    const costValue = parseInt(cost);

    // duration과 cost는 양의 정수만 받아야함
    if (isNaN(durationValue) || !Number.isInteger(durationValue) || durationValue < 1) {
        alert("여행일수는 1이상의 숫자만 기재할 수 있습니다");
        return;
    }

    if (isNaN(costValue) || !Number.isInteger(costValue) || costValue < 0) {
        alert("여행비용은 0이상의 숫자만 기재할 수 있습니다");
        return;
    }

모두 or조건을 만들어서 3개 중 하나라도 참이 되면 알림을 띄우고 함수가 종료되게 만들었습니다.
isNaN은 입력값이 숫자인지 파악해줍니다. 만약 해당값이 숫자가 아니라면 True를 보냅니다.
!Number.isInteger은 입력값이 정수가 아닌지를 파악해주고 정수가 아니라면 False를 보냅니다.
그리고 마지막은 1 혹은 0보다 큰 수인지를 조건으로 만들었습니다.

프론트에서는 이 정도의 예외처리를 해주었으나 아직 백엔드에서의 처리가 남아있습니다.

사실 숫자형 필드의 경우 IntegerField를 사용했는데 이전까지 PositiveIntegerField를 생각하지 못하고 있었습니다.

cost = models.IntegerField("경비")

이번 피드백을 받고 양의 정수를 기입하는 모든 필드를 PositiveIntegerField로 변경해주었습니다.

cost = models.PositiveIntegerField("경비")
duration = models.PositiveIntegerField("기간")

이제 JS를 변경해 백엔드로 요청을 보내더라도 필드유형이 양의정수가 아니면 받지 않아 잘못 기입 된 값을 저장하지 않게 되었습니다.

이번 피드백을 보내주신 분에게는 너무도 감사했습니다. 그 분이 아니였다면 이런 치명적인 보안오류가 발생할지 생각도 못한채 프로젝트가 흘러갈뻔했는데 너무 다행이였습니다.

profile
이제 막 개발 배우는 코린이

0개의 댓글