
CVE-2026-22732의 최소 재현 — Spring Security HTTP 헤더가 조용히 누락됨
CVE-2026-22732의 최소 재현 — 컨트롤러 코드가 서블릿 응답에 직접 쓸 때 Spring Security HTTP 응답 헤더가 자동으로 삭제됩니다.
Spring Security는 기본적으로 "지연(lazy)" 헤더 작성을 사용합니다. 컨트롤러가 response.getOutputStream()에 쓰거나, response.flushBuffer()를 호출하거나, setIntHeader()를 통해 Content-Length를 설정하면, Spring Security가 보안 헤더(X-Frame-Options, X-Content-Type-Options, Cache-Control, Strict-Transport-Security 등)를 주입하기 전에 응답이 커밋됩니다.
CVSS 3.1: 9.1 (치명적) — 인증이나 사용자 상호작용이 필요하지 않습니다.
src/main/java/com/example/vuln/
├── VulnApplication.java # Spring Boot 진입점
├── SecurityConfig.java # 보안 헤더 구성 (X-Frame-Options, CSP 등)
└── VulnController.java # 1개의 안전한 + 3개의 취약한 엔드포인트
src/test/java/com/example/vuln/
└── HeaderVerificationTest.java # 취약한 버전에서 실패하는 테스트
| 엔드포인트 | 취약 여부 | 트리거 |
|---|---|---|
GET /safe | 아니요 | 일반적인 Spring MVC 반환 |
GET /vuln/stream | 예 | response.getOutputStream()에 쓰기 |
GET /vuln/flush | 예 | response.flushBuffer() 호출 |
GET /vuln/content-length | 예 | setIntHeader()로 Content-Length 설정 |
./mvnw spring-boot:run
그런 다음 curl로 확인합니다:
# 안전 — 헤더 존재
curl -i http://localhost:8080/safe
# 취약 — 보안 헤더 누락
curl -i http://localhost:8080/vuln/stream
curl -i http://localhost:8080/vuln/flush
curl -i http://localhost:8080/vuln/content-length
./mvnw test
취약한 버전에서는 vuln* 테스트가 실패합니다 (헤더 누락).
패치된 버전(6.5.9+ / 7.0.4+)에서는 모든 테스트가 통과합니다.
pom.xml을 업데이트하여 패치된 Spring Security 버전을 사용합니다:
<spring-security.version>6.5.9</spring-security.version>