【入門編】HTTP/1.1のTransfer-Encodingヘッダーの優先順位とセキュリティ – HTTPプロトコル・通信規格実践ガイド

こんにちは!ネットワークの深淵を旅する皆さん、ようこそ。

今日は、Web通信の「お作法」であるHTTPの中でも、特に「トラブルの火種」になりやすいTransfer-Encoding(転送符号化)とContent-Length(コンテンツ長)の仲の悪さについてお話しします。

「ヘッダーが二つあると何が起きるの?」という素朴な疑問から、ネットワークの裏側で暗躍する「リクエストスマグリング」というサイバー攻撃の影まで、一緒に紐解いていきましょう。

—

荷物のサイズは誰が決める?:二つの配送ルール

Web通信を「郵便」に例えてみましょう。あなたがWebサイト(サーバー)にリクエストを送ることは、手紙を送るのと同じです。

通常、手紙には「この手紙は全部で100グラムありますよ」というContent-Length(中身の長さ)を書きますよね。受け取る側は「なるほど、100グラム受け取ったら封筒を閉じよう」と判断できます。

ところが、HTTP/1.1にはもう一つ、別のルールがあります。それがTransfer-Encoding: chunked(分割転送)です。

「ちぎって送る」というアイデア

例えば、巨大なファイルを送る時、全部用意できるまで待っていたら時間がかかりますよね。そこで、「まずは最初の塊(100バイト)を送るよ!次はまた送るから待ってて!」というふうに、荷物をバラバラにして送るのがこの「chunked」という仕組みです。

ここで問題が発生します。「荷物の総量(Content-Length)」と「バラバラ送る宣言(Transfer-Encoding)」が同時に書かれていたら、サーバーはどっちを信じればいいのでしょうか?

—

悪夢の始まり:解釈のズレが招く「スマグリング」

ネットワークの世界には、ユーザーとサーバーの間に「プロキシサーバー(中継役)」や「ロードバランサー(交通整理役)」が立っていることがよくあります。

ここで、「中継役はContent-Lengthを信じ、サーバーはTransfer-Encodingを信じる」といった「解釈のズレ」が起きると、とんでもないことが起きます。

リクエストスマグリングの仕組み

1. 攻撃者: 「100バイトのデータだよ(実際は200バイト送る)」という嘘のContent-Lengthと、Transfer-Encodingを混ぜて送る。
2. 中継役: 「ふむ、Content-Lengthが100バイトだから、ここまでが1通目の手紙だな」と判断してサーバーに転送する。
3. サーバー: 「Transfer-Encodingがあるから、最後まで読み切るぞ」と判断する。
4. 結果: サーバーの中に、「中継役が読み飛ばしたはずの残り100バイト」が、次のリクエストの「頭」として混入してしまう!

これが「HTTPリクエストスマグリング」です。前の人の荷物が、次の人の手紙に紛れ込んで届いてしまう……。これを使えば、他人のIDでログインしたり、管理者権限を盗み見たりできてしまう可能性があるのです。

—

実務で意識すべきポイント:どう防ぐ?

インフラエンジニアとして、この脆弱性を避けるために意識すべきは「曖昧さを排除する」ことです。

1. 二重設定を禁止する

現代の強力なWebサーバー(NginxやApacheなど)では、Content-LengthとTransfer-Encodingが共存している場合、エラーを返すか、どちらかを強制的に無視する設定が可能です。

Nginxの例:セキュリティ対策として、曖昧なリクエストを拒否する設定
不正なヘッダーが含まれる場合に400 Bad Requestを返す
if ($http_transfer_encoding ~ “chunked”) {
# chunkedが指定されている場合はContent-Lengthを無効化する処理を入れるなど
# 最近のバージョンでは自動で厳格化されています
}

2. 常に最新のミドルウェアを使う

HTTPの解釈ルールは、長年の攻撃と対策の歴史そのものです。最新のサーバーソフトは、こうしたヘッダーの競合に対して非常に厳格になっています。「昔のままで動いているから大丈夫」と思わず、定期的なアップデートが最大の防御です。

3. デバッグ時はパケットを覗く

もし「なんかリクエストが変な挙動をするな」と思ったら、Wiresharkなどのツールでパケットを見てみてください。

  • Content-Length: 数値で書かれていますか?
  • Transfer-Encoding: chunked と書かれていますか?

もし両方が混在していたら、それがトラブルの犯人である確率が非常に高いです。

—

まとめ:ネットワークは「信頼」でできている

今回お話しした「ヘッダーの解釈のズレ」は、まさに「人間同士のコミュニケーションのすれ違い」と同じです。「言ったつもり」「聞いたつもり」の間に、悪意ある隙間が生まれるのです。

HTTPプロトコルはシンプルですが、それゆえに解釈の余地が残されています。皆さんが現場でトラブルに遭遇したとき、「プロトコルの仕様書」だけでなく、「中継役とサーバーの間で、どう言葉が翻訳されているか?」を想像してみてください。

そうやって一歩ずつパケットの旅路を追っていくことで、皆さんは間違いなく「ネットワークの達人」へ近づいていきます。

それでは、また次回の深淵でお会いしましょう!

コメント

タイトルとURLをコピーしました