CVE-2026-22732 的最小复现 — 当控制器代码直接写入 servlet 响应时,Spring Security HTTP 响应头会被静默丢弃。
Spring Security 默认使用“惰性”响应头写入机制。当控制器写入 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 # 在易受攻击版本上会失败的测试
./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>
| 端点 | 是否易受攻击 | 触发方式 |
|---|
GET /safe | 否 | 正常 Spring MVC 返回 |
GET /vuln/stream | 是 | 写入 response.getOutputStream() |
GET /vuln/flush | 是 | 调用 response.flushBuffer() |
GET /vuln/content-length | 是 | 通过 setIntHeader() 设置 Content-Length |