Header Injection
Also Known As
HTTP header injection
response header injection
TL;DR
User input included in an HTTP response header without stripping newlines enables response splitting and redirect hijacking.
Explanation
HTTP headers are separated by CRLF (\r\n). If an attacker injects a newline into a header value, they can inject additional headers or even a second HTTP response body — a technique called HTTP Response Splitting. This can be used to poison caches, hijack redirects, or inject HTML/JavaScript. Prevention: strip all \r and \n characters from any user-supplied value before including it in a header().
How It's Exploited
GET /page?lang=en%0d%0aSet-Cookie:admin=1
# Injects: Set-Cookie: admin=1 as a separate response header
# Injects: Set-Cookie: admin=1 as a separate response header
Common Misconception
✗ Header injection is just a cosmetic issue affecting formatting. Injecting newlines enables full HTTP response splitting, XSS via reflected headers, cache poisoning, and open redirect.
Why It Matters
Injecting headers via user input can redirect users, poison caches, or enable XSS through response splitting — all from a single unvalidated string.
Common Mistakes
- Passing unsanitised user input to PHP's header() function, especially in Location or Set-Cookie headers.
- Trusting X-Forwarded-For or Referer headers and reflecting them into responses.
- Not stripping \r and \n from any value that ends up in an HTTP header.
- URL-decoding values before passing to header() without re-stripping control characters.
Code Examples
✗ Vulnerable
// User input injected into header — attacker can inject newlines
\$lang = \$_GET['lang'];
header("Content-Language: \$lang");
// ?lang=en%0d%0aSet-Cookie:admin=1 → injects extra header
✓ Fixed
// Allowlist approach
\$allowed = ['en', 'fr', 'de', 'es', 'ja'];
\$lang = in_array(\$_GET['lang'] ?? 'en', \$allowed, true)
? \$_GET['lang'] : 'en';
header("Content-Language: \$lang");
// If dynamic values are unavoidable, strip CR/LF:
\$clean = str_replace(["\r", "\n"], '', \$value);
header("X-Custom: \$clean");
References
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
20
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
Amazonbot 6
Google 2
Ahrefs 2
ChatGPT 2
Majestic 1
Perplexity 1
Also referenced
How they use it
crawler 12
crawler_json 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟠 High
⚙ Fix effort: Low
⚡ Quick Fix
Strip or reject any \r or \n characters from values passed to header(); in PHP 8.0+ header() throws on CRLF automatically
📦 Applies To
PHP 5.0+
web
🔗 Prerequisites
🔍 Detection Hints
header( with user-supplied value not sanitised for CRLF characters
Auto-detectable:
✓ Yes
semgrep
psalm
⚠ Related Problems
🤖 AI Agent
Confidence: High
False Positives: Low
✓ Auto-fixable
Fix: Low
Context: Line
CWE-113
CWE-644