메뉴 건너뛰기

app

헤더에 숨어든 공격자: CWE-113 HTTP 응답 분할 방지 전략

suritam92026.01.17 19:20조회 수 5댓글 0

    • 글자 크기

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 대응 및 안전한 헤더 처리 자바 코드 예시

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
 
public class HeaderSecurityManager {
    private static final Logger logger = LoggerFactory.getLogger(HeaderSecurityManager.class);
 
    public void setSafeHeader(HttpServletResponse response, String headerName, String value) {
        if (value == null) return;
 
        // [CWE-113 조치] 줄바꿈 문자(CR, LF) 제거를 통한 응답 분할 방어
        // %0d, %0a 등 인코딩된 문자도 포함하여 처리하는 것이 안전합니다.
        String cleanValue = value.replaceAll("\r", "").replaceAll("\n", "");
        
        // 추가 보안: 특수문자 제어 (비즈니스 로직에 맞게 조정)
        cleanValue = cleanValue.trim();
 
        try {
            logger.debug("Setting safe header: {} = {}", headerName, cleanValue);
            response.setHeader(headerName, cleanValue);
        } catch (IllegalArgumentException e) {
            // [CWE-754, CWE-390] 부적절한 헤더 값에 대한 예외 처리
            logger.debug("Invalid header value detected and rejected: {}", e.getMessage());
        }
    }
 
    public void setSafeCookie(HttpServletResponse response, String name, String value) {
        // [CWE-113 조치] 쿠키 값에서도 줄바꿈 문자 제거 필수
        String cleanValue = value.replaceAll("[\r\n]", "");
        
        Cookie cookie = new Cookie(name, cleanValue);
        cookie.setHttpOnly(true); // XSS 방어
        cookie.setSecure(true);   // HTTPS 통신 권장
        
        response.addCookie(cookie);
        logger.debug("Safe cookie set: {}", name);
    }
}

코멘트: HTTP 응답 분할 방어의 핵심은 "헤더는 단 한 줄이어야 한다"는 원칙을 지키는 것입니다. 공격자가 주입하는 줄바꿈 문자는 헤더와 본문의 경계를 무너뜨리는 치명적인 무기가 될 수 있습니다. logger.debug()를 통해 비정상적인 헤더 삽입 시도를 기록하되, 외부 입력이 HTTP 프로토콜의 구조를 파괴하지 못하도록 철저히 정규화하는 것이 시큐어 코딩의 기본입니다.

 
    • 글자 크기
숫자의 한계를 이용한 논리 파괴: CWE-190 정수형 오버플로우 (by suritam9) 내부망 침투의 교두보: CWE-918 SSRF 방지 전략 (by suritam9)

댓글 달기

첨부 (0)
위로