HTTP Header Injection (CRLF Injection)
User-controlled input included in HTTP response headers without sanitization, allowing attackers to inject arbitrary headers or split the response into two separate HTTP responses.
How It Works
HTTP headers end with `\r\n` (carriage return + line feed). If you put user input into a header value, an attacker can inject `\r\n` to end the current header and start a new one — or even inject a blank line to start a fake response body. This enables cache poisoning, XSS via injected headers, and session fixation.
// BAD: user input in redirect header
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const lang = searchParams.get('lang'); // attacker injects \r\nSet-Cookie: evil=1
return new Response(null, {
headers: { 'Location': `/home?lang=${lang}` }
});
}// GOOD: validate and sanitize header values
export async function GET(req: Request) {
const { searchParams } = new URL(req.url);
const lang = searchParams.get('lang') ?? 'en';
// Strip CRLF characters — they have no place in header values
const safeLang = lang.replace(/[\r\n]/g, '');
const allowed = ['en', 'es', 'fr'];
if (!allowed.includes(safeLang)) return new Response('Bad Request', { status: 400 });
return new Response(null, { headers: { 'Location': `/home?lang=${safeLang}` } });
}Real-World Example
CRLF injection was found in popular frameworks and CDNs, enabling attackers to inject arbitrary cookies or cache poisoned responses to other users. Node.js's http module throws an error on CRLF in headers since v14, but custom header-building code can still be vulnerable.
How to Prevent It
- Strip \r and \n from any user input before using it in response headers
- Validate header values against an allowlist instead of blocklist
- Use framework-provided redirect functions that handle encoding automatically
- Never build redirect URLs by concatenating unsanitized query parameters
Affected Technologies
Data Hogo detects this vulnerability automatically.
Scan Your Repo FreeRelated Vulnerabilities
LDAP Injection
highUser input inserted into LDAP search filters without escaping, allowing attackers to manipulate directory queries, bypass authentication, or extract sensitive directory data.
XXE — XML External Entity Injection
highXML parsers configured to process external entity references, allowing attackers to read arbitrary files from the server or trigger SSRF by crafting a malicious XML payload.
Email Header Injection
mediumUnsanitized user input used in email To, From, CC, or Subject fields, allowing attackers to inject additional recipients and turn your email server into a spam relay.
Log Injection
lowUser-supplied input written to logs without sanitization, allowing attackers to forge log entries, hide their tracks, or inject malicious content into log files.