핵심 인사이트 (3줄 요약)

  1. 본질: 예외 처리(Exception Handling) 미흡으로 인한 정보 노출은 스택 트레이스(Stack Trace), DB 오류 메시지, 서버 경로 등이 공격자에게 직접 노출되는 심각한 취약점이다.
  2. 가치: 오류 메시지 하나가 SQL 테이블 구조, 서버 내부 경로, 사용 프레임워크 버전을 노출하여 후속 공격의 발판이 된다.
  3. 판단 포인트: 사용자에게 노출되는 오류 메시지는 "일반화된 안내 문구"만 표시하고, 상세 정보는 서버 측 로그에만 기록하는지 확인한다.

Ⅰ. 개요 및 필요성

예외 처리(Exception Handling)의 보안 목표는 두 가지다. 첫째, 시스템 내부 정보를 외부에 노출하지 않는 것. 둘째, 예외 발생 시에도 서비스가 안전하게 지속되는 것이다. 행정안전부 개발보안 가이드의 "오류 메시지를 통한 정보 노출" 항목은 Critical 등급으로 분류되어 있다.

노출 정보 유형예시공격자 활용 방법
스택 트레이스NullPointerException at com.app.UserDAO:45패키지 구조, 클래스 명, 라인 번호 파악
DB 오류 메시지Table 'users' doesn't exist테이블명, DB 종류 파악
SQL 구문 노출Syntax error in SQL: SELECT * FROM user WHERE id=SQL 인젝션 공격 포인트 확인
서버 경로/usr/local/tomcat/webapps/app/WEB-INF/파일 업로드 경로 추측
프레임워크 버전Apache Struts 2.3.5알려진 취약점(CVE) 적용
  • 개발 환경(DEBUG 모드)과 운영 환경(PRODUCTION 모드) 설정 미분리
  • 전역 예외 처리기(Global Exception Handler) 미구현
  • catch (Exception e) { e.printStackTrace(); } 패턴 남용
┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│ Problem      │──▶│ Core Idea    │──▶│ Expected Gain │
└──────────────┘    └──────────────┘    └──────────────┘
  • 📢 섹션 요약 비유: 오류 메시지를 그대로 노출하는 것은 "고장난 자판기가 내부 회로도를 유리창에 붙여두는 것"이다. 수리 직원만 볼 수 있어야 할 정보가 모든 사람에게 공개된다.

Ⅱ. 아키텍처 및 핵심 원리

┌────────────────────────────────────────────────────────────┐
│              예외 처리 2-Channel 아키텍처                    │
│                                                            │
│  예외 발생                                                  │
│       │                                                    │
│       ▼                                                    │
│  ┌──────────────────────────────────────────────┐          │
│  │         전역 예외 처리기 (Global Handler)      │          │
│  │   @ControllerAdvice / web.xml error-page      │          │
│  └────────────────────┬─────────────────────────┘          │
│                       │                                    │
│           ┌───────────┴──────────────┐                     │
│           │                          │                     │
│           ▼                          ▼                     │
│  ┌──────────────────┐   ┌─────────────────────────┐        │
│  │  사용자 응답      │   │  서버 내부 로그           │        │
│  │  (Public)        │   │  (Private)               │        │
│  │                  │   │                          │        │
│  │ "서비스 오류가    │   │ [ERROR] 2026-04-21       │        │
│  │  발생했습니다.    │   │ NullPointerException     │        │
│  │  관리자에게       │   │ at UserDAO.java:45       │        │
│  │  문의하세요."     │   │ SQL: SELECT * FROM...   │        │
│  │                  │   │ Stack: ...               │        │
│  └──────────────────┘   └─────────────────────────┘        │
│    브라우저에 표시           로그 파일/SIEM에만 기록          │
└────────────────────────────────────────────────────────────┘
// 취약한 코드 (Bad)
@GetMapping("/user/{id}")
public User getUser(@PathVariable Long id) {
    try {
        return userService.findById(id);
    } catch (Exception e) {
        e.printStackTrace();  // 스택 트레이스가 로그에 노출
        throw e;              // 예외를 그대로 전파 → HTTP 500 + 스택 트레이스
    }
}

// 안전한 코드 (Good)
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleAll(Exception e) {
        log.error("Unhandled exception", e);  // 서버 로그에만 기록
        return ResponseEntity.status(500)
            .body(new ErrorResponse("서비스 오류가 발생했습니다."));
    }
}
항목설명포인트
핵심 역할입력·상태·출력을 분리하는 책임 경계구현보다 경계를 먼저 본다.
제어 지점조건, 이벤트, 정책이 만나는 곳병목과 결합이 생기는 곳이다.
검증 포인트테스트·로그·모니터링으로 확인할 지점운영 가능성이 설계 품질을 결정한다.
  • 📢 섹션 요약 비유: 전역 예외 처리기는 "병원 접수창구"다. 의사의 진단 내용(상세 오류)은 의무기록실(서버 로그)에 보관되고, 환자(사용자)에게는 "다음에 다시 오세요"라는 안내만 전달한다.

Ⅲ. 비교 및 연결

패턴보안성유지보수성감리 판정
e.printStackTrace() 직접 출력❌ 취약△ 개발 중에만 유용지적 필수
HTTP 500 + 스택 트레이스 반환❌ 취약지적 필수
전역 핸들러 + 일반 메시지 반환✅ 안전권장 패턴
오류 코드 기반 응답✅ 안전✅ 추적 용이권장 패턴
오류 발생 시 자동 알림(Slack/이메일)✅ 안전✅✅우수 사례
설정 항목개발 환경운영 환경
spring.profiles.activedevprod
server.error.include-stacktracealwaysnever
server.error.include-messagealwaysnever
logging.level.rootDEBUGWARN
spring.mvc.log-request-detailstruefalse
┌─────────────────────────────────────────────────────────────┐
│          개발 vs 운영 오류 응답 차이                          │
│                                                             │
│  [개발 환경 응답]          [운영 환경 응답]                   │
│  {                         {                               │
│    "error": "500",           "error": "서비스 오류",         │
│    "message": "NullPointer", "code": "ERR_500",            │
│    "trace": "at com.app...", "message": "관리자 문의"        │
│    "path": "/api/user/1"   }                               │
│  }                                                          │
│       ↑ 공격자에게 노출 금지      ↑ 안전한 응답              │
└─────────────────────────────────────────────────────────────┘
  • 📢 섹션 요약 비유: 개발 환경과 운영 환경의 오류 설정 차이는 "연습장과 공연장의 차이"다. 연습 중엔 감독이 큰 소리로 지시를 외치지만, 공연 중엔 관객에게는 들리지 않게 귓속말로만 한다.

Ⅳ. 실무 적용 및 기술사 판단

점검 단계점검 방법판정 기준
1단계: 설정 파일 확인application-prod.properties 검토include-stacktrace=never
2단계: 고의 오류 유발존재하지 않는 URL 접근, 잘못된 파라미터 전송일반 오류 메시지만 반환
3단계: SQL 오류 확인' OR '1'='1 입력 후 응답 확인DB 오류 메시지 미노출
4단계: 소스코드 검색e.printStackTrace() 패턴 검색운영 코드에서 0건
5단계: HTTP 헤더 확인응답 헤더의 Server:, X-Powered-By: 확인서버 정보 미노출

HTTP 응답 헤더에서도 서버 정보가 노출될 수 있다.

# 취약한 헤더 예시
Server: Apache/2.4.49 (Ubuntu)
X-Powered-By: PHP/7.4.3

# 안전한 설정
Server: (제거 또는 임의값)
X-Powered-By: (제거)
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

로그에 저장되는 상세 정보 또한 보안 관리가 필요하다. 로그에 개인정보(Personal Information), 비밀번호, 세션 토큰이 기록되지 않도록 마스킹(Masking) 처리가 필요하다.

판단 체크리스트

  1. 위험 시나리오와 점검 범위가 문서로 합의되었는가?
  2. 지표·증적·로그가 재현 가능하게 수집되는가?
  3. 예외 상황과 오탐·미탐 처리 절차가 있는가?
  4. 재시험 또는 후속 조치 기준이 수치로 정의되었는가?
  • 📢 섹션 요약 비유: HTTP 응답 헤더에서 서버 버전을 노출하는 것은 "강도에게 '우리 집 자물쇠는 A사 2018년형'이라고 스티커를 붙여두는 것"이다. 버전 정보만으로도 알려진 취약점을 즉시 찾아낼 수 있다.

Ⅴ. 기대효과 및 결론

예외 처리 정보 노출을 방지하면 공격자가 시스템 구조를 역추적하는 첫 번째 발판을 차단한다. 많은 APT(Advanced Persistent Threat, 지능형 지속 공격) 사례에서 초기 정찰 단계의 핵심 정보는 오류 메시지 분석을 통해 수집되었다. 운영 환경의 오류 응답 일반화와 서버 측 로깅 체계 구축은 최소 비용으로 최대 효과를 얻는 보안 기초 조치다.

감리인은 단순히 코드 패턴 탐색에 그치지 않고, 실제 고의 오류를 유발하여 응답 내용을 확인하는 블랙박스 테스트를 병행해야 한다.

확장 방향은 ① Policy as Code, ② Continuous Audit, ③ 인공지능(AI, Artificial Intelligence) 기반 이상 탐지와 결합하는 것이다.

  • 📢 섹션 요약 비유: 예외 처리 감리는 "비상구 표시등이 제대로 작동하는지, 하지만 비상구 열쇠 위치는 외부에 공개되지 않는지" 모두를 확인하는 이중 점검이다.

📌 관련 개념 맵

관계개념설명
상위 개념SW 개발보안 43개 항목오류 메시지 정보 노출 포함
상위 개념OWASP A09 - Security Misconfiguration오류 설정 미흡 분류
하위 개념전역 예외 처리기 (Global Exception Handler)@ControllerAdvice, web.xml
하위 개념스택 트레이스 (Stack Trace)내부 코드 구조 노출 정보
연관 개념SIEM (Security Information and Event Management)로그 통합 보안 모니터링
연관 개념HTTP 보안 헤더Server, X-Powered-By 제거

📈 관련 키워드 및 발전 흐름도

오류 분류 → 예외 처리 정보 노출 감리 → 관측 가능성·보안 로그

👶 어린이를 위한 3줄 비유 설명

  1. 프로그램이 오류 났을 때 내부 메시지를 그대로 보여주는 건 "넘어진 다음에 엑스레이 사진을 모두에게 보여주는 것"이야.
  2. 안전한 오류 처리는 "넘어졌을 때 '잠깐만요'라고만 말하고, 자세한 진단은 의사 선생님(서버 로그)한테만 전달"하는 거야.
  3. 해커는 오류 메시지 하나에서 집 열쇠 위치를 알아낼 수 있으니까, 항상 "괜찮아요!"라고만 말하는 연습이 필요해.