1. HTTP 응답 분할의 위험성
CWE-113은 사용자로부터 입력받은 값이 HTTP 응답 헤더에 포함될 때, 줄바꿈 문자(CRLF: \r\n, %0d%0a)를 적절히 필터링하지 않아 발생합니다. 공격자는 이 문자를 주입하여 하나의 HTTP 응답을 두 개 이상의 응답으로 분리(Splitting)할 수 있습니다. 이렇게 분할된 가짜 응답은 브라우저나 캐시 서버(Proxy)에 전달되어, 악성 스크립트를 실행(XSS)하거나 특정 페이지의 캐시를 오염시켜 다른 사용자에게 조작된 화면을 보여주는 캐시 포이즈닝(Cache Poisoning) 공격으로 이어집니다.
2. 흔히 발생하는 취약한 패턴
주로 리다이렉트 처리(Location 헤더), 쿠키 설정(Set-Cookie 헤더), 또는 커스텀 헤더에 사용자 이름이나 페이지 주소를 삽입할 때 발생합니다. 예를 들어, 사용자가 입력한 userId가 그대로 쿠키에 담긴다면, 공격자는 admin\r\nContent-Length: 0\r\n\r\nHTTP/1.1 200 OK\r\n...와 같은 값을 주입하여 서버가 의도하지 않은 두 번째 응답을 브라우저에 강제로 전송하게 만듭니다.
3. 실무적 대응: 헤더 값 정규화 및 라이브러리 활용
가장 확실한 방어법은 헤더에 삽입되는 모든 입력값에서 줄바꿈 문자를 원천적으로 제거하는 것입니다.
• CRLF 제거: 사용자 입력값에서 \r (CR)과 \n (LF) 문자를 강제로 삭제하거나 공백으로 치환합니다.
• 최신 WAS 및 프레임워크 사용: 최신 버전의 톰캣(Tomcat)이나 스프링(Spring) 프레임워크는 헤더에 줄바꿈 문자가 포함될 경우 자동으로 예외를 던지거나 필터링하는 기능을 내장하고 있습니다.
• 화이트리스트 검증: 헤더에 들어갈 수 있는 값의 형식을 제한(알파벳, 숫자 등)하고, 그 외의 문자가 포함된 경우 요청을 거부(CWE-112 준수)합니다.
4. CWE-113 대응 및 안전한 헤더 처리 자바 코드 예시
코멘트: HTTP 응답 분할 방어의 핵심은 "헤더는 단 한 줄이어야 한다"는 원칙을 지키는 것입니다. 공격자가 주입하는 줄바꿈 문자는 헤더와 본문의 경계를 무너뜨리는 치명적인 무기가 될 수 있습니다. logger.debug()를 통해 비정상적인 헤더 삽입 시도를 기록하되, 외부 입력이 HTTP 프로토콜의 구조를 파괴하지 못하도록 철저히 정규화하는 것이 시큐어 코딩의 기본입니다.
댓글 달기