WebアプリのセキュリティといえばSQLインジェクションやXSSがよく語られますが、HTTPの基本構造を突く「CRLFインジェクション」は、開発者にも情シス担当者にも見落とされがちな脆弱性です。キャッシュポイズニングやCookieの不正操作など、気づかないうちに大きな被害を生む可能性があります。
この記事では、CRLFインジェクション(HTTPレスポンス分割攻撃)の仕組み・具体的な被害パターン・現場で使える防御手順を解説します。Web開発者はもちろん、情シスの方やセキュリティ担当者にも知っておいてほしい内容です。

CRLFインジェクションとは?
CRLFインジェクション(CRLF Injection)は、HTTPプロトコルが使用する改行コード「CR(キャリッジリターン、\r)」と「LF(ラインフィード、\n)」を悪用した攻撃手法です。この2文字を組み合わせたCRLFはHTTPヘッダーとボディを区切る役割を担っており、攻撃者がこれをリクエストに含めて送ることで、Webサーバーのレスポンスヘッダーを改ざんできます。
特に「HTTPレスポンス分割(HTTP Response Splitting)」と呼ばれる発展形では、1件のHTTPリクエストから2つの独立したレスポンスを生成させることが可能になります。これによって偽ページの埋め込みやキャッシュポイズニングが引き起こされます。
OWASPはこの脆弱性をインジェクション系の攻撃に分類しており、Webアプリケーションのセキュリティ上、見逃せないリスクです。知名度が低い分、テストや監査で見落とされる現場も少なくありません。
攻撃の仕組み(敵を知る)
1. CRLFとHTTPの関係
HTTPでは、レスポンスヘッダーの各行はCRLF(\r\n)で区切られています。ヘッダー全体の終わりは空白行(\r\n\r\n)で表され、それ以降がレスポンスボディになります。
以下はHTTPレスポンスの構造例です。
# HTTPレスポンスの構造(概念) HTTP/1.1 302 Found Location: https://www.example.com/ Set-Cookie: session=abc123; HttpOnly (空白行 = \r\n\r\n) (ここからボディ)
Webアプリがユーザー入力をそのままLocationヘッダーやSet-Cookieヘッダーに埋め込む実装になっている場合、攻撃者はその入力値に改行コードを含めることでヘッダーを分断できます。
2. 攻撃者はどこを狙うか
攻撃が成立しやすい箇所は、ユーザー入力がHTTPレスポンスヘッダーに反映される場所です。
・URLリダイレクト: Locationヘッダーにパラメータをそのまま埋め込む実装
・Cookie設定: Set-Cookieにユーザー入力を含める実装
・カスタムヘッダー: X-Custom-Headerなどに入力値を直接埋め込む実装
URLエンコードで改行コードは%0D(CR)・%0A(LF)と表現されます。攻撃者はこれを使ってリダイレクト先URLなどに改行コードを埋め込み、ヘッダーを不正に操作します。
3. HTTPレスポンス分割攻撃の流れ
CRLFインジェクションが発展した「HTTPレスポンス分割」では、二重の改行(空白行)を注入することで、1つのHTTPレスポンスの中に攻撃者が作成した偽のレスポンスヘッダーとボディを同居させることができます。
# 攻撃後のレスポンスイメージ(概念) HTTP/1.1 302 Found Location: https://legitimate.com Set-Cookie: evil=injected; Path=/ # 攻撃者が注入した偽レスポンス HTTP/1.1 200 OK Content-Type: text/html Content-Length: (任意) (攻撃者が作成した偽ページのHTML)
プロキシサーバーやCDNがこの偽レスポンスをキャッシュすると、その後に同じURLへアクセスした別のユーザーも攻撃者のコンテンツを受け取ることになります。
具体的な被害パターン
1. Cookie注入によるセッション乗っ取り
攻撃者が不正なSet-Cookieヘッダーを注入すると、被害ユーザーのブラウザに攻撃者が意図した値のCookieを設定させることができます。これをセッション固定化攻撃と組み合わせると、正規ユーザーのセッションを攻撃者が乗っ取る(セッションハイジャック)につながる可能性があります。
2. キャッシュポイズニング
企業内のプロキシサーバーやCDN(コンテンツデリバリネットワーク)が介在する環境では、HTTPレスポンス分割によって攻撃者のコンテンツがキャッシュに保存されてしまうことがあります。その後、同じURLへアクセスした別のユーザーが、本来のコンテンツではなく攻撃者のコンテンツを正規ページとして受け取る危険があります。
3. XSSへの転用
CRLFインジェクションを通じてContent-TypeヘッダーをHTMLに書き換え、そこにスクリプトを埋め込む手口では、実質的にXSSと同じ効果をもたらすことがあります。通常のXSSフィルターがURLのエンコードをチェックするだけでは不十分なケースがあるのも、この攻撃の厄介な点です。
4. フィッシング誘導
偽のLocationヘッダーを注入することで、ユーザーを攻撃者が用意したフィッシングサイトへ誘導できます。正規サイトのURLを踏み台にしているため、ユーザーが疑いにくいのが特徴です。
具体的な防御手順
1. 入力値のバリデーションとサニタイジング
最も根本的な対策は、HTTPヘッダーに渡すすべての値から改行コード(\r、\n)を除去・エンコードすることです。URLパラメータをLocationヘッダーに埋め込む処理や、Cookieに値を設定する処理では、必ず改行コードのチェックを実施します。
# Python実装例: ヘッダーに埋め込む前に改行コードを除去する # NG: ユーザー入力をそのままヘッダーに使う # response.headers['Location'] = user_input # OK: 改行コードを除去してから使う def sanitize_header_value(value): return value.replace('\r', '').replace('\n', '') safe_url = sanitize_header_value(user_input) response.headers['Location'] = safe_url
サニタイズ対象の文字は最低でも以下の4パターンをカバーします。
・\r(CR、%0D)
・\n(LF、%0A)
・%0D(URLエンコード形式)
・%0A(URLエンコード形式)
2. フレームワークの安全なAPIを使う
多くの現代的なWebフレームワーク(Django・Ruby on Rails・Spring・Express等)は、HTTPヘッダーを設定する際にCRLFを自動的に除去または拒否する仕組みを持っています。フレームワークのAPIを正しく使うことが安全な実装の第一歩です。
・フレームワーク提供のリダイレクト関数を使う(生のヘッダー操作を避ける)
・カスタムヘッダーを設定する場合もフレームワークのAPIを通す
・ユーザー入力をヘッダーに含める場合はホワイトリスト方式で許可値のみ使う
注意が必要なのは、フレームワークの対策は「高レベルAPIを使ったとき」に機能するという点です。低レベルのソケット通信や独自実装でヘッダーを操作している場合、フレームワークの保護は受けられません。
3. セキュリティヘッダーで多層防御
CRLFインジェクション自体の直接的な防御ではありませんが、被害の拡大を防ぐセキュリティヘッダーを設定しておくことで、二次的なXSSやキャッシュポイズニングのダメージを軽減できます。
# Nginxの設定例: セキュリティヘッダー追加 add_header X-Content-Type-Options nosniff; add_header X-Frame-Options SAMEORIGIN; add_header Content-Security-Policy "default-src 'self'"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"; add_header Cache-Control "no-store, no-cache";
セキュリティヘッダーの詳細な設定方法は、姉妹サイトLinuxMaster.JPのサーバー設定ガイドも参考にしてください。
4. WAFでの追加検知
WAF(Webアプリケーションファイアウォール)は、CRLFインジェクションの典型的なパターン(%0D%0A等のURL文字列)を検出するシグネチャを持っています。ただしWAFは補助的な対策であり、入力バリデーションの代替にはなりません。WAFを導入している場合でも、サーバーサイドのサニタイジングを省略しないことが原則です。
WAFの仕組みと導入方法については、WAFとは?Webアプリケーションファイアウォールの仕組み・選び方・導入手順をわかりやすく解説も参照してください。
中小企業でも今日からできること
情シス担当者1人の環境でも、以下の確認だけでリスクを大きく下げられます。
・フレームワークのバージョン確認: 使用しているWebフレームワークが最新かどうか確認する。古いバージョンはCRLF対策が不十分な場合がある
・リダイレクト処理の棚卸し: URLリダイレクト処理を実装している箇所を開発者に確認し、Locationヘッダーへの直接埋め込みがないか把握する
・WAFシグネチャの確認: WAFを導入している場合、CRLFインジェクションのシグネチャが有効になっているか確認する
・脆弱性スキャンの定期実施: OWASP ZAP等の無料ツールを月1回以上実施し、ヘッダーインジェクションを検出するテストを含める
・外部公開URLの確認: すべてのURLパラメータがHTTPヘッダーに反映されていないか、開発者に確認する
脆弱性スキャンの始め方については、情シス1人でもできる脆弱性スキャン入門|無料ツールで社内ネットワークの弱点を可視化する方法を参考にしてください。
よくある誤解と注意点
「最新フレームワークを使っているから大丈夫」は過信です
多くのフレームワークはCRLFを自動的にサニタイズしますが、フレームワークの保護が効くのは高レベルAPIを通した操作のときだけです。独自でHTTPヘッダーを操作するコードや、低レベルのソケット通信を使う実装では対策が漏れることがあります。コードレビューで独自実装箇所を定期的に確認することが大切です。
「WAFがあれば安心」は過信です
WAFはCRLFインジェクションの多くのパターンを検出できますが、二重エンコードやUnicodeエスケープを使ったバリアント(変形)では検知を回避されることがあります。根本対策は必ずサーバーサイドの入力バリデーションです。
ライブラリのCVEにも注意が必要です
人気のオープンソースライブラリでも、CRLFインジェクション関連の脆弱性がCVEとして定期的に公開されます。利用しているライブラリのセキュリティアドバイザリ(GitHub Security Advisories・JVN等)を定期的に確認し、パッチを適用する運用を整えましょう。
HTTPリクエストスマグリングとの違い
CRLFインジェクションと混同されやすい攻撃に「HTTPリクエストスマグリング」があります。前者はレスポンスヘッダーへの改行注入、後者はリクエストのパーシング差異を突くもので、仕組みも対策も異なります。HTTPリクエストスマグリングとは?仕組み・被害例・対策をわかりやすく解説もあわせて読むとそれぞれの違いが整理できます。

本記事のまとめ
| 項目 | 内容 |
|---|---|
| 攻撃の原理 | HTTPヘッダーに改行コード(\r\n)を注入し、ヘッダー構造を破壊する |
| 主な被害 | Cookie注入・キャッシュポイズニング・XSS転用・フィッシング誘導 |
| 狙われる箇所 | URLリダイレクト・Set-Cookie・カスタムHTTPヘッダーへのユーザー入力 |
| 根本対策 | ヘッダーに渡す値から\r・\nを除去するサニタイジング |
| フレームワーク依存の注意点 | 高レベルAPI使用時のみ自動保護が効く。独自実装は自前でバリデーションが必要 |
| 補助的対策 | WAF・セキュリティヘッダー(CSP・HSTS等)・定期的な脆弱性スキャン |
CRLFインジェクションは「知名度が低いから大丈夫」と考えるのが最も危険です。OWASPのガイドラインでも継続的に言及されている実在する脅威です。まず自社のWebアプリでユーザー入力がHTTPヘッダーに反映される箇所を特定し、入力バリデーションが適切に実装されているかを確認することから始めましょう。
セキュリティヘッダー全般の設定については、HTTPSだけでは足りない|セキュリティヘッダー完全ガイド(CSP・HSTS・X-Frame-Options)設定と確認方法も参考にしてください。
PR
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版(徳丸浩/SBクリエイティブ)
CRLFインジェクションを含むWebアプリケーションの脆弱性全般を体系的に学べる定番書。攻撃の仕組みから安全な実装方法まで実践的に解説されており、開発者・情シス担当者どちらにも役立ちます。
