utsuroi request smuggling labs知識ベース 01 / 01
HTTP Request Smuggling · Knowledge Base
01

HTTP Request Smuggling の基礎

When proxy and origin disagree on where one request ends

フロントエンド(リバースプロキシ・CDN)とバックエンド(オリジンサーバ)で HTTP リクエストの境界の解釈が異なると、攻撃者は次のリクエストの先頭にコマンドを忍ばせることができる。1接続を共有する全ユーザを攻撃可能。

1. なぜ起きるか #why

HTTP/1.1 でリクエストの長さを示す方法は2つあり、どちらか一方が使われる:

仕様上、両方が指定された場合は TE を優先する。しかし実装によって扱いが違う。フロントエンドが CL を、バックエンドが TE を採用すると、両者が認識する「リクエストの終わり」がずれる。

2. CL.TE 攻撃 #cl-te

フロントが Content-Length、バックエンドが Transfer-Encoding を採用するパターン。

POST / HTTP/1.1
Host: shop.utsuroi.example.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED_REQ
↑ ここまでが攻撃者の HTTP リクエスト

フロントは Content-Length=13 と判断し、空行から13バイト分(0\r\n\r\nSMUGGLED_REQ)を「1つのリクエスト本文」として扱う。一方バックエンドは Transfer-Encoding を見て、0\r\n\r\n でリクエスト終了と判断 → その後の SMUGGLED_REQ を「次のリクエストの先頭」と解釈

これによって、攻撃者の「smuggled」リクエストが、後続の正規リクエストの先頭に「結合」される事態が起きる。

3. TE.CL 攻撃 #te-cl

フロントが Transfer-Encoding、バックエンドが Content-Length のパターン。逆方向だが原理は同じ。

近年は Transfer-Encoding 自体を標準化された形でしか受け付けない実装が増え、TE.TE 系(両者が TE を見るが、いずれかが「曖昧な TE ヘッダ」で混乱)の攻撃も頻出。

4. 何ができるか #impact

5. 正しい防御 #defense

  1. HTTP/2 をエンドツーエンドで使う — HTTP/2 は明確なフレーム長ベースなので、CL/TE の曖昧さがない。HTTP/2 が一般化した今、最も有効な対策
  2. あいまいなリクエストを拒否 — Content-Length と Transfer-Encoding が両方ある、TE が複数ある、改行コードが奇妙、等のリクエストはフロントエンドで 400 を返す
  3. 同じ実装で揃える — フロントとバックエンドで同じ HTTP パーサ実装を使う(困難な場合が多い)
  4. 1接続1リクエスト — Connection: close を強制(パフォーマンス低下)
  5. Front-end のバージョンを最新に — Cloudflare、AWS ALB、nginx、HAProxy 等は smuggling 検出パッチを継続的に出している