以下の内容はhttps://cysec148.hatenablog.com/entry/2025/09/16/153455より取得しました。


初心者向けHTTPリクエストスマグリング入門:CLとTEの食い違いをやさしく解説

Hello there, ('ω')ノ

前提:扱うサンプル(行末は \r\n と数えます)

クライアントがフロントに送った文字列(省略せず可視化):

POST / HTTP/1.1\r\n
Host: vulnerable\r\n
Content-Length: 20\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n
GET /admin HTTP/1.1\r\n
Host: vulnerable\r\n

ポイント:Content-Length: 20Transfer-Encoding: chunked が同時に存在している(=矛盾)。 フロント(ここでは「Content-Length を信じる」実装)を仮定します。


ステップ 0 — 用語整理(簡単に)

  • クライアント:攻撃者や普通のユーザ。最初にこの長いデータを送る側。
  • フロント:ロードバランサ/リバースプロキシ等。クライアントから受け取り、バックエンドへ転送する。
  • バックエンド:実アプリが動くサーバ。フロントから受け取ったバイト列を解析する。
  • 送信済み部分:フロントがバックエンドに既に送ったバイト列。
  • 残り(余り):フロントがまだバックエンドに渡していないバイト列(フロント側のバッファに残っているもの)。

ステップ 1 — フロントが「どこまで」送るか(今回の前提)

Content-Length: 20 を信じるフロントは「本文(body)」をちょうど20バイト送ります。 本文の先頭はヘッダ終端(空行 \r\n)の直後から始まります。

本文(可視化):

0\r\n\r\nGET /admin HTTP/1.1\r\nHost: vulnerable

最初の20バイトは文字列としては次までです:

0\r\n\r\nGET /admin HTTP
                ^-- ここで切れて('P' が20バイト目)

つまりフロント→バックへ送信済みなのは(ヘッダ +)本文20バイト分まで。残りは以下

/1.1\r\nHost: vulnerable\r\n

これが「フロントに残っている」状態です。


ステップ 2 — バックエンドが受け取った「送信済み部分」の中身と最初の判断

バックエンドは受け取ったストリーム(ヘッダ+本文20バイト)を順に処理します。重要なのはバックエンド側のパーサの優先ルール

  • もしバックエンドが Transfer-Encoding: chunked を優先する実装なら、先頭の 0\r\n\r\n を「空チャンク=本文終了」として解釈します。 → この時点でバックエンドは POST の本文を終了したと判断する。次に流れてくるデータは新しいリクエストの開始だと見なす準備をする。

  • もしバックエンドが Content-Length を優先する実装なら、フロントが送った20バイトをそのまま「POSTの本文」として消費する(=前のリクエストに吸収)。 → 結果として GET /admin の先頭は POST の本文の一部であり、次のリクエストは壊れる・来ない。

今回「フロントが CL を使って20バイト送った」ケースの最も典型的な/攻撃者が狙う流れは、バックエンドが Transfer-Encoding を優先するパターンです。以下、それを中心に説明します。


ステップ 3 — 残り(/1.1\r\nHost: vulnerable)はいつどのようにバックエンドに渡るか(タイムライン)

この続きはcodocで購入



以上の内容はhttps://cysec148.hatenablog.com/entry/2025/09/16/153455より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14