Hello there, ('ω')ノ
Apache Tomcat は、Java Servlet や JSP を実行するための軽量かつ高速なサーバーとして広く使われています。しかし 2022 年に発見された CVE-2022-42252 は、Tomcat の設定次第で HTTP Request Smuggling 攻撃を許してしまう重大な欠陥でした。ここでは、攻撃者がどのようにこの脆弱性を突くのか、その思考過程を追って解説します。
脆弱性の本質
Tomcat の server.xml にある rejectIllegalHeader が false に設定されている場合、不正な Content-Length ヘッダ を含むリクエストが拒否されません。
さらに Tomcat がリバースプロキシの背後に配置され、そのプロキシも同様に「不正ヘッダを拒否できない」場合、フロントエンドとバックエンドで解釈がずれて リクエスト密輸(Request Smuggling) が可能になります。
攻撃者の思考ステップ
1. 「ソース→シンク」を意識する
- ソース:攻撃者が完全に制御できるリクエストヘッダ(特に Content-Length)
- シンク:Tomcat がヘッダを解析して次のリクエスト境界を決める処理
→ 攻撃者は「不正なヘッダ値を食わせたらどう解釈されるか?」を試します。
2. コンテキストを把握する
HTTP にはリクエストの終端を決める2種類の方法があります。
- Content-Length:リクエストボディの長さをバイト数で指定
- Transfer-Encoding: chunked:チャンクごとに長さを指定
仕様上は Transfer-Encoding が優先されますが、サーバーによって解釈が異なることがあります。 → ここに「ズレ」が生まれる余地があります。
3. 実際のPoC(攻撃例)
Tomcat を以下のように設定した場合:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" rejectIllegalHeader="false" />
攻撃者は次のようなリクエストを送ります:
POST / HTTP/1.1 Host: victim.com:8080 Content-Length: 12\x00073 # ← 不正な制御文字入り ...
- 本来であれば RFC 7230 に従い 400 Bad Request を返すべき
- しかし脆弱なバージョンでは 200 OK として処理が継続される
→ これにより、後続のリクエストが「密輸」される可能性が生まれます。
4. 影響範囲
攻撃者がこのズレを利用できると:
- セッション乗っ取り:別ユーザーの Cookie を奪取
- キャッシュポイズニング:悪意あるレスポンスをキャッシュに混入
- 認証バイパス:通常なら拒否されるリクエストが処理される
- 任意リクエストの注入:フロントエンドの監視をすり抜け、バックエンドに不正リクエストを実行させる
修正と防御策
この脆弱性は CVSS 7.5(高リスク) と評価されています。対策は以下の通りです。
Tomcat をアップデート
- 10.1.1 以上
- 10.0.27 以上
- 9.0.68 以上
- 8.5.83 以上
→ 修正版では、
skipLine処理に追加チェックが入り、不正な Content-Length を検出すると 例外を投げて 400 エラー を返すようになりました。rejectIllegalHeader を true に設定 デフォルトが
falseのバージョン(8.5.xなど)は特に注意。WAFやリバースプロキシで不正ヘッダをブロック フロントで「怪しいヘッダ」を排除すれば、バックエンドに届かないようにできます。
まとめ:攻撃者の視点での理解
攻撃者がこの脆弱性を突くときの考え方はシンプルです。
- どのヘッダを細工できるか?
- その細工がフロントとバックで異なる解釈を生むか?
- そのズレを利用して次のリクエストを「密輸」できるか?
たったこれだけの観点で、Tomcat の設定ミスやバージョンの古さを突くことが可能です。
Best regards, (^^ゞ