Skip to main content

예외 처리 미흡

점검 목적​

잘못된 자료형, 누락된 값, 만료된 인증 정보 같은 비정상 상황에서도 애플리케이션이 안전하게 거절되는지 확인한다. 상세 오류가 외부에 노출되는지, 검증 예외가 권한 통과로 이어지는지, 오류 뒤 사용한 자원이 정상적으로 정리되는지가 핵심이다.

스택 트레이스나 디버그 정보의 일반적인 노출은 정보 노출, 계정 존재 여부 차이는 인증에서 더 넓게 다룬다. 결제 일부 처리, 포인트·사용 횟수 불일치, 허용되지 않은 상태 전이는 비즈니스 로직, 중복 callback과 동시 처리 문제는 Race Condition으로 분리한다. 이 문서는 예외가 발생했을 때 안전하게 실패하는지에 집중한다.

유형 구분​

유형특징실무 판단
상세 오류 노출스택 트레이스, 경로, 쿼리, 내부 주소가 응답에 포함됨노출 값의 민감도와 실제 활용 가능성을 확인
예외 시 통과검증 도중 오류가 나면 거부하지 않고 진행함보호 데이터나 기능이 실제로 열리는지 확인
응답 불일치같은 실패가 상태 코드·본문·시간에서 다르게 보임사용자·자원 존재 여부를 안정적으로 구분할 수 있는지 확인
자원 정리 실패오류 뒤 파일·세션·락·임시 상태가 남음한 번의 통제된 실패 뒤 정상 요청 영향 확인

진단 절차​

Step 1. 정상과 예상된 실패 기준 기록​

  • 정상 요청과 함께 필수 필드 누락, 인증 없음, 권한 없음, 존재하지 않는 자원 요청을 각각 저장한다.
  • 상태 코드, 본문 구조, 응답 헤더, 쿠키 변화, 응답 시간과 후속 상태를 기록한다.
  • 400, 401, 403, 404, 409, 422처럼 의도된 실패와 처리하지 못한 500을 구분한다.

Step 2. 입력별 최소 오류 유도​

  • 한 요청에서 한 값만 null, 빈 문자열, 잘못된 자료형, 누락 값으로 바꾼다.
  • 숫자는 0, -1, 정상 범위를 조금 넘는 값부터 확인한다.
  • JSON은 문법 오류, 중복 키, 배열·객체 바꾸기를 필요한 입력에만 적용한다.
  • 대용량 본문, 장시간 지연, 동시 요청은 기본 오류 확인에 사용하지 않는다.

Step 3. 어느 계층의 오류인지 구분​

  • CDN·WAF·리버스 프록시가 만든 HTML 오류인지 애플리케이션 JSON 오류인지 확인한다.
  • Server, Via, X-Request-ID, traceparent와 본문 오류 식별자를 함께 본다.
  • 같은 요청을 다시 보내 오류가 반복되는지 확인한다. 일회성 게이트웨이 오류는 앱 결함과 분리한다.

Step 4. 보호 동작과 자원 정리 확인​

  • 200과 500만 보지 말고 보호 데이터, 세션, 쿠키와 권한이 바뀌었는지 확인한다.
  • 업로드·편집 잠금·일회용 토큰은 오류 뒤 같은 테스트 객체를 정상적으로 다시 사용할 수 있는지 확인한다.
  • 외부 인증 서비스의 실패를 mock할 수 있다면 접근이 거부되는지만 확인한다. 주문·결제 상태 정합성은 비즈니스 로직 문서로 분리한다.

상황별 빠른 선택​

현재 상황첫 확인
숫자 ID를 받는 조회 API문자열, 0, -1, 존재하지 않는 정상 형식 ID
JSON 생성·수정 API필수 필드 누락, null, 문자열·객체 자료형 교체
인증된 API토큰 없음, 잘못된 토큰, 권한 없는 테스트 계정
업로드·편집·일회용 토큰오류 한 번 뒤 정상 요청이 가능한지 확인
외부 인증 연동mock 실패 응답에서 접근이 거부되는지 확인
500 또는 HTML 오류원시 응답 헤더와 생성 계층 확인
로그인·비밀번호 재설정존재하는 테스트 계정과 없는 계정의 응답 비교

페이로드 노트​

1. 필수 값과 자료형을 한 개씩 변경​

이럴 때 사용: JSON API가 기대하지 않은 값을 어떻게 처리하는지 가장 먼저 확인할 때 사용한다.

{"quantity":1,"product_id":"TEST-100"}

아래 값은 한 번에 하나씩 바꾼다.

{"quantity":null,"product_id":"TEST-100"}
{"quantity":"1","product_id":"TEST-100"}
{"quantity":{},"product_id":"TEST-100"}

검증 오류가 일반화된 400·422 응답으로 끝나는지, 내부 클래스명이나 쿼리가 노출되는지, 예외 뒤 보호 기능이 기본 허용값으로 처리되는지 확인한다.

2. 경로·쿼리 숫자의 경계 확인​

이럴 때 사용: 숫자형 자원 ID, 페이지 번호, 수량을 받는 요청에서 사용한다.

GET /api/orders/not-a-number HTTP/1.1
GET /api/orders/0 HTTP/1.1
GET /api/orders/-1 HTTP/1.1

문자열에서 변환 스택 트레이스가 나오는지, 음수가 다른 자원으로 정규화되는지, 존재하지 않는 ID가 권한 검사를 건너뛰는지 확인한다. 정상적인 400이나 404만 반환되면 취약점이 아니다.

3. JSON 문법과 Content-Type 오류 확인​

이럴 때 사용: API 파서, 프레임워크 전역 오류 처리, 게이트웨이와 앱의 응답 차이를 확인할 때 사용한다.

POST /api/profile HTTP/1.1
Content-Type: application/json

{"display_name":"test"
POST /api/profile HTTP/1.1
Content-Type: text/plain

{"display_name":"test"}

깨진 JSON은 보통 400, 지원하지 않는 형식은 415가 자연스럽다. 500이 나오더라도 내부 정보, 상태 변화, 반복 재현이 없으면 오류 처리 개선 후보일 뿐 보안 취약점으로 바로 확정하지 않는다.

4. 인증·권한 오류가 안전하게 닫히는지 확인​

이럴 때 사용: 인증 또는 권한 검사 과정에서 파싱·검증 예외가 발생할 수 있는 보호 API에 사용한다.

GET /api/account/summary HTTP/1.1
Authorization: Bearer invalid.test.token
GET /api/admin/summary HTTP/1.1
Authorization: Bearer <LOW_PRIVILEGE_TEST_TOKEN>

잘못된 인증 정보는 거절되어야 한다. 오류 본문이 반환되면서 보호 데이터도 함께 포함되거나, 권한 검사 예외 뒤 기본 관리자·익명 권한으로 실행되면 fail-open이다. 401과 403의 차이는 정상적인 인증·인가 구분일 수 있으므로 그 자체를 문제로 보지 않는다.

5. 외부 인증 실패 시 접근 거부 확인​

이럴 때 사용: 테스트 환경에서 SSO·토큰 검증 서비스의 실패 응답을 mock 또는 프록시로 바꿀 수 있을 때 사용한다.

모의 응답확인할 것
timeout로컬 세션이나 기본 권한이 발급되지 않음
401·서명 오류외부 검증 실패로 접근이 종료됨
잘못된 JSON파싱 예외 뒤 인증 성공값을 사용하지 않음

외부 서비스를 직접 느리게 하거나 중단하지 않는다. 결제·주문 상태, 재시도, callback 정합성은 비즈니스 로직에서 확인한다.

6. 오류 응답의 노출 정보 확인​

이럴 때 사용: 앞선 최소 변조에서 앱 또는 프레임워크 오류가 반환됐을 때 사용한다.

노출 값실무 판단
오류 식별자·요청 ID운영자 추적용이면 일반적으로 정상
프레임워크 이름단독 영향은 낮고 정확한 버전·취약 상태를 추가 확인
소스 경로·함수·줄 번호내부 구조 파악에 직접 도움이 되는지 확인
테이블·컬럼·원본 쿼리SQLi 등 다음 진단에 사용할 수 있는지 확인
내부 호스트·포트·URL내부 접근 경로와 결합 가능한지 확인
비밀번호·토큰·연결 문자열원문을 재노출하지 말고 마스킹해 사용 가능성만 확인

안전한 외부 응답은 원인을 상세히 설명하지 않아도 된다.

{
"error":"request_failed",
"request_id":"req-7f3a"
}

7. 계정·자원 존재 여부는 차이만 확인​

이럴 때 사용: 로그인, 비밀번호 재설정, 초대, 자원 조회에서 같은 실패가 서로 다르게 보일 때 사용한다.

존재하는 테스트 계정 + 잘못된 값
존재하지 않는 계정 + 같은 잘못된 값

본문, 상태 코드, 길이와 시간을 비교한다. 여기서는 오류 응답이 일관적인지만 보고, 계정 목록 확인이나 후속 이메일 검증은 인증의 사용자 열거 절차로 이어간다.

8. 오류 뒤 자원 정리 여부 확인​

이럴 때 사용: 업로드, 임시 예약, 편집 잠금, 일회용 토큰 처리 중 한 번의 오류가 발생한 경우 사용한다.

  • 오류 후 같은 테스트 파일을 정상 업로드할 수 있는지 확인한다.
  • 테스트 초안의 편집 잠금이 해제됐는지 확인한다.
  • 실패한 일회용 토큰이 잘못 소모되거나 다시 유효해지지 않았는지 확인한다.
  • 임시 객체가 사용자에게 보이거나 다음 요청에 재사용되지 않는지 확인한다.

반복 오류로 자원을 고갈시키지 않고, 통제된 실패 한 번과 정상 요청 한 번으로 확인한다. 동시성 자체가 핵심이면 Race Condition 절차로 분리한다.

9. Burp에서 응답 차이 정리​

이럴 때 사용: 상태 코드는 같지만 본문이나 헤더가 미묘하게 다를 때 사용한다.

  • Repeater에서 정상, 예상 실패, 예외 유도 요청을 각각 저장한다.
  • Comparer로 본문과 헤더 차이를 비교한다.
  • Logger 또는 HTTP history에서 redirect, refresh 요청, 후속 API 호출을 확인한다.
  • 자동 스캔 결과는 동일한 최소 요청으로 다시 재현한다.

우회 매트릭스​

관찰 결과다음 확인판단
잘못된 JSON이 CDN HTML로 거절됨정상 JSON의 자료형 오류로 앱 계층 확인앱 오류 처리까지 도달하지 않음
모든 오류가 같은 JSON임헤더, 쿠키, 후속 상태를 비교일관된 본문은 긍정적 단서
응답은 200이고 본문에 error가 있음실제 상태·데이터·부수 효과 확인상태 코드만으로 성공 판정 금지
한 번만 500이 발생함같은 최소 요청을 재전송일회성 오류는 근거 부족
스택 트레이스는 없고 요청 ID만 있음ID에 내부 정보가 포함되는지 확인무작위 추적 ID는 정상
404가 권한 없음과 자원 없음에 동일함본문·시간·부수 효과 비교자원 존재를 숨기는 설계일 수 있음
응답 시간만 다름동일 조건을 여러 번 교차 측정반복되는 차이만 후보
개발 환경에서만 상세 오류가 보임외부 접근성과 실제 데이터 연결 확인공개된 개발 환경이면 별도 영향 판단
프록시 오류와 앱 오류 모양이 다름Via, 요청 ID, 서버 로그 연결 확인생성 계층을 나눠 기록

취약 판정​

확정​

  • 인증·권한·서명 검증 중 예외가 발생했는데 보호 데이터나 기능이 허용된다.
  • 외부 인증 서비스의 실패가 성공으로 처리되어 로컬 세션이나 접근 권한이 발급된다.
  • 오류 응답에 사용 가능한 자격증명, 토큰, 연결 문자열 또는 민감 데이터가 노출된다.
  • 한 번의 통제된 실패 뒤 잠금·임시 객체·일회용 상태가 남아 다른 정상 흐름에 영향을 준다.

후보 또는 보류​

  • 처리하지 못한 입력에서 500만 발생한다.
  • 무작위 요청 ID나 일반적인 오류 코드만 반환된다.
  • 프레임워크 이름이나 내부 경로가 보이지만 추가 활용 가능성이 확인되지 않는다.
  • 401, 403, 404가 상황에 맞게 서로 다르게 반환된다.
  • 시간 차이가 작거나 반복되지 않는다.
  • mock 없는 운영 환경이라 외부 인증 실패를 안전하게 확인할 수 없다.

영향 상승​

  • 예외로 다른 사용자·관리자 권한 또는 조직 경계를 넘는다.
  • 노출된 비밀이 실제 내부 서비스 인증이나 다른 취약점 재현에 사용된다.
  • 오류 상태가 여러 요청이나 사용자에게 지속된다.
  • 제한된 단일 요청만으로도 서비스 가용성 저하가 반복 재현된다.

참고자료​