ネットワークの「伝言ゲーム」を悪用せよ!HTTPリクエストスマグリングの深淵
こんにちは!インフラエンジニアの現場では、日々パケットという名の「手紙」が世界中を飛び交っています。
今日は、そんなWeb通信の裏側で密かに行われる「HTTPリクエストスマグリング」という、ちょっとスリリングな攻撃手法についてお話しします。名前は難しそうですが、仕組みは意外と身近な「手違い」から生まれるものなんです。
一緒に紐解いていきましょう!
—
1. そもそも、Webの通信はどうやって境界を決めているの?
Webサイトを見る時、私たちのブラウザはWebサーバーに対して「このページをちょうだい!」というリクエストを送ります。でも、Webサーバーの前には、よく「プロキシサーバー」や「ロードバランサー」といった「受付係」が立っていますよね。
この「受付係」が受け取った大量の手紙を、奥にいる「バックエンド(本物のサーバー)」にまとめて渡すわけです。
ここで重要なのが、「どこで手紙が終わり、どこからが次の手紙か」という境界線です。
手紙の境界線を決める2つのルール
昔から、この境界を決めるために主に2つの方法が使われてきました。
1. Content-Length(コンテンツ・レングス):
「この手紙は全部で◯◯バイトあるよ!」と重さを先に伝える方法。
2. Transfer-Encoding(トランスファー・エンコーディング):
「手紙をいくつかに分割して送るから、最後には『終わりだよ』という合図を出すね!」と分割して送る方法。
本来なら、このどちらか一方が使われるはずなのですが……現代の複雑なネットワークでは、この2つが同時に送られてくることがあります。
—
2. なぜ「手違い」が起きるのか?
ここからが本題です。もし、「受付係」と「奥のサーバー」で、「どちらのルールを優先するか」の解釈が違っていたらどうなるでしょうか?
例えば、悪意のある攻撃者がこんな手紙を作ったとします。
POST / HTTP/1.1
Host: example.com
Content-Length: 13 // 「全体で13バイトだよ!」と主張
Transfer-Encoding: chunked // 「分割して送るよ!」と主張
0 // chunkedの終わりを示す合図
// ここに次の悪意あるリクエストを「密輸(スマグリング)」!
悲劇の始まり
1. 受付係(フロントエンド)は「`Transfer-Encoding`があるから、こっちを優先しよう」と判断します。`0`という合図を見て、「よし、ここで手紙は終わりだ!」と認識します。
2. 奥のサーバー(バックエンド)は「`Content-Length`の方を優先しよう」と判断します。すると、13バイト分だけ読み取って、「あ、まだ続きがあるな…」と、次に届くはずの別のユーザーの手紙の一部を、前の手紙の「続き」だと勘違いして処理してしまいます。
これがリクエストスマグリング(密輸)です。本来届くはずのないリクエストが、バックエンドの中で勝手に連結されて処理されてしまう。まさに、郵便局の仕分けミスを突いた犯罪のようなものですね。
—
3. 実務で遭遇するリスクと対策
この脆弱性が放置されていると、どんなことが起きるのでしょうか。
- セッションの乗っ取り: 他のユーザーのリクエストを自分のものとして取り込み、認証情報を盗み出す。
- キャッシュ汚染: 偽のコンテンツをサーバーに記憶させ、他の人にも偽サイトを見せる。
どうやって防ぐの?
現場のインフラエンジニアとして、これを防ぐための鉄則はシンプルです。
- HTTP/2 または HTTP/3 への移行:
HTTP/1.1の複雑な境界線のルールを捨て、より厳密な通信プロトコルを使うのが今のトレンドです。
- フロントとバックの解釈を統一する:
ロードバランサーとサーバーの設定で、優先するヘッダーの解釈を一致させます。
- WAF(Web Application Firewall)の活用:
「あ、このリクエスト、ヘッダーの組み合わせが怪しいな」と判断して遮断する盾を置くことが大切です。
—
まとめ:ネットワークは「信頼」の上に成り立っている
「受付係」と「奥のサーバー」が、同じ言語(プロトコル)で、同じルールで話していると信じている。その「思い込み」の隙間を突くのが、リクエストスマグリングの本質です。
インフラエンジニアという仕事は、こうした「当たり前」の裏側にある「もしも」を想像し、設計する仕事です。難しい言葉に惑わされず、「今、パケットは誰に何を伝えているのか?」をイメージする癖をつけるだけで、皆さんの視界はグッと広がるはずですよ!
また次回の記事で、より深いインフラの世界を冒険しましょう。それでは!
コメント