CVE-2026-22732 の最小再現 — コントローラコードがサーブレットレスポンスに直接書き込む際に、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(Critical) — 認証やユーザー操作は不要です。
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 # 脆弱なバージョンで FAIL するテスト
| エンドポイント | 脆弱性 | トリガー |
|---|---|---|
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>