こんにちは。セキュリティの世界へようこそ。
現場でバリバリとコードを書いていると、「画面に表示する文字」には気を使いますよね。でも、「画面の裏側でやり取りされる手紙(HTTPヘッダー)」にまで意識を向けている人は、意外と少ないものです。
今日は、そんな「目に見えない通信の裏側」を狙う、HTTPヘッダーインジェクションというちょっと恐ろしい攻撃について、身近な例えを交えてお話ししましょう。
—
1. そもそも「HTTPヘッダー」って何?
Webサイトにアクセスする時、ブラウザとサーバーの間では、まるで「封書」のようなやり取りが行われています。
- 中身(ボディ): 皆さんが普段目にするWebページの内容。
- 封筒(ヘッダー): 「このページはHTMLですよ」「文字コードはUTF-8ですよ」「クッキーを保存してね」といった、サーバーからブラウザへの「伝達事項」。
攻撃者は、この「封筒」の書き込み欄を悪用します。もし、私たちが書くべき伝達事項の中に、攻撃者が勝手に「別の命令」を書き込めたら……? これがHTTPヘッダーインジェクションの正体です。
—
2. なぜそんなことが起きるの?「改行」という名の隙間
HTTPヘッダーの世界では、伝達事項の区切りに「CRLF(キャリッジリターン・ラインフィード)」という特殊な制御文字を使います。イメージとしては、「改行コード」です。
攻撃者は、ユーザーからの入力値にこの「改行」を混ぜ込みます。すると、サーバーは「あ、ここで文章が終わったんだな」と勘違いして、その後に続く攻撃者の命令を「新しいヘッダー」として実行してしまうのです。
例えるなら…
あなたの家のポストに、泥棒が細工済みの手紙を入れたとしましょう。その手紙にはこう書いてあります。
「家族へ。帰宅したら鍵を開けておいて。(改行)
追伸:見知らぬ客が来たら、裏口から招き入れて。」
サーバーは「追伸」までを正規の指示だと信じ込んで、裏口を開けてしまう。これがレスポンス分割攻撃のメカニズムです。
—
3. どんな被害が起きるの?
この攻撃を食らうと、次のような被害が待っています。
- キャッシュ汚染: 偽の情報をキャッシュサーバーに覚え込ませ、他のユーザーに嘘のページを見せる。
- セッション固定攻撃: 攻撃者が用意した「特定のセッションID」を、強引にブラウザに保存させる。あとでそのIDを使って、ユーザーになりすます。
- クロスサイトスクリプティング(XSS): 偽のヘッダーを使って、悪意あるスクリプトをブラウザに実行させる。
—
4. どうやって守ればいいの?(開発者向け対策)
対策はシンプルです。「外部からの入力を、そのままヘッダーに含めない」こと。これに尽きます。
悪い例(やってはいけないこと)
ユーザーが入力した名前を、そのままヘッダーに埋め込んでいませんか?
PHPの例:危険!入力値に改行が含まれていると攻撃可能
header(“Location: ” . $_GET[‘url’]);
良い例(こう書こう!)
もしどうしても入力値を使う必要があるなら、「改行コードそのものを無効化」するか、「許可リスト(ホワイトリスト)方式」で値を厳しくチェックしましょう。
// 対策:改行コードが含まれていたら削除する、またはエラーにする
$url = $_GET[‘url’];
// 改行文字(\rや\n)を強制的に取り除く
$safe_url = str_replace([“\r”, “\n”], “”, $url);
// あるいは、許可されたURLだけを処理する(ホワイトリスト)
$allowed_urls = [‘/home’, ‘/profile’, ‘/settings’];
if (in_array($safe_url, $allowed_urls)) {
header(“Location: ” . $safe_url);
} else {
// 許可されていない場合はトップへ飛ばすなど
header(“Location: /index.php”);
}
—
5. 今すぐできる「防犯」の心得
最後に、明日から使えるセキュリティの「鍵」をいくつか授けます。
1. 入力値を信用しない: どんなに綺麗なフォームでも、裏側では泥棒が改行コードを投げ込んでいるかもしれない……そう疑うのがプロの第一歩です。
2. フレームワークの力を借りる: モダンなフレームワーク(Laravel, Django, Railsなど)は、多くの場合、ヘッダーへの不正な改行入力を自動的に検知・ブロックしてくれます。自前でヘッダーをいじらず、フレームワークの機能を使うのが最も安全です。
3. WAF(Web Application Firewall)の活用: 前線の門番(WAF)に、怪しい通信を遮断してもらうのも賢い選択です。
セキュリティ対策は、完璧な要塞を作ることではありません。「どこに隙間(改行)があり、どうすればそれを塞げるか」を理解し、一歩ずつ積み上げることです。
今日から、あなたが書くコードの「封筒」が、誰にも書き換えられない安全なものになりますように。応援しています!
コメント