🪤 부적절한 예외 처리 시뮬레이터 KISA A-4 · 부적절한 예외 처리

두 가지 안티패턴: (1) 광범위한 빈 catch가 예외를 통째로 삼켜 보안 검사가 조용히 건너뛰어집니다; (2) 핸들러가 전체 스택 트레이스·SQL 오류·내부 경로를 사용자에게 노출합니다. 둘 다 오류를 취약점으로 바꿉니다.

① 취약한 예외 핸들러 VULNERABLE

안티패턴을 선택하세요. 삼킴: 빈 catch가 권한/검증 실패를 숨겨 동작이 그대로 진행됩니다. 노출: 핸들러가 원본 예외(스택 트레이스·SQL·파일 경로)를 응답에 그대로 echo — 스택·DB 스키마를 알려주는 정보 노출.
공격자에게 보이는 HTTP 응답:
(실행 전)

② 안전한 핸들러: 구체적 catch · 안전 메시지 · 서버 로그 SECURE

수정본은 보안 관련 실패를 절대 삼키지 않고(중단), 구체적 예외를 잡으며, 상세 내용은 상관관계 id와 함께 서버에만 기록하고, 사용자에게는 일반 메시지만 반환합니다.
사용자에게 보이는 HTTP 응답:
(실행 전)
내부 서버 로그 (사용자에게 미노출):
(실행 전)

③ 취약 vs 안전 코드

VULNERABLE
// (1) 삼킴 — 보안 검사 실패가 사라진다
try {
    checkLicense(user);        // 실패하면 예외
    enablePremiumFeature();    // 그래도 실행됨?!
} catch (Exception e) {
    // 아무것도 안 함 — 예외 통째로 삼킴
}

// (2) 노출 — 내부 정보를 사용자에게
try {
    runQuery("SELECT ... WHERE name='" + name + "'");
} catch (Exception e) {
    e.printStackTrace(response.getWriter()); // 스택/SQL 노출
    response.send(e.toString());             // 경로/버전 노출
}
SECURE
// (1) 보안 실패는 절대 삼키지 않는다
try {
    checkLicense(user);
} catch (LicenseException e) {
    log.warn("license check failed", e); // 서버 로그
    return deny();                       // 동작 중단
}
enablePremiumFeature();                  // 통과한 경우만

// (2) 구체적 catch + 일반 메시지 + 서버 로그
try {
    runParameterizedQuery(name);         // SQLi 자체도 차단
} catch (SQLException e) {
    String id = UUID.randomUUID().toString();
    log.error("query failed id=" + id, e); // 상세는 서버만
    return error(500, "처리 중 오류 (ref " + id + ")"); // 일반 메시지
}
삼킴은 보안 통제가 실패했다는 유일한 신호를 없애 — 공격자가 인가된 것처럼 진행합니다. 노출은 스택 트레이스·SQL 오류·경로로 프레임워크 버전·쿼리 구조·파일시스템 지도를 공격자에게 넘겨 다음 공격을 가속합니다. 방어: 구체적 예외만 잡기 · 보안 경로에 빈 catch 금지 · 상세는 상관관계 id와 함께 서버에만 로깅 · 클라이언트에는 일반 메시지(+id)만 · 운영에서 프레임워크 디버그 페이지 비활성화.
⚠️ 교육용 시뮬레이션입니다. 스택 트레이스·SQL 오류·서버 로그는 페이지 내부에서 만든 mock이며, 실제 예외·데이터베이스·파일시스템과 무관합니다.