CWE-93: CRLF Injection
Overview
CRLF Injection occurs when untrusted user input is included in HTTP headers or other protocol fields without proper validation or encoding, allowing attackers to inject carriage return (CR) and line feed (LF) characters to manipulate protocol behavior.
OWASP Classification
A05:2025 - Injection
Risk
High: Attackers can perform HTTP response splitting, set malicious headers, or inject content into responses, leading to XSS, cache poisoning, or session fixation.
Remediation Steps
Core principle: Never allow untrusted data to inject CRLF or protocol delimiters; validate/encode before generating structured text (headers, logs, protocols).
Trace the Data Path and Locate the Vulnerability
Analyze how untrusted data reaches HTTP header construction:
- Review the flaw details to identify the specific file, line number, and code pattern
- Source: Where untrusted data enters (user input, external file, database, network request)
- Sink: HTTP header setting functions (
response.headers[],setHeader(),addHeader()) - String concatenation: Look for untrusted data being directly inserted into header values
- Understand the data flow from source to sink
Encode or Remove CR/LF Characters (Primary Defense)
Sanitize all untrusted data before using it in HTTP headers:
- Remove or encode carriage return (
\r) and line feed (\n) characters - Use
replace()or regex to strip CR/LF:user_input.replace('\r', '').replace('\n', '') - Also consider removing tab (
\t) and null byte (\0) characters - Apply sanitization before any header manipulation
- Follow the secure code examples provided in language-specific guidance
Use Framework Security Features
Leverage built-in framework protections:
- Prefer frameworks that automatically encode or validate headers
- Use framework APIs that handle header construction safely
- Avoid manual header construction with string concatenation
- Use typed header objects when available (e.g., Response objects)
- Let the framework handle encoding of special characters
Validate Input for Protocol Fields (Defense in Depth)
Add input validation as an additional security layer:
- Enforce strict type, length, and format checks on all untrusted header values
- Validate expected patterns (URLs, tokens, content types)
- Use allowlists for enumerated values (e.g., redirect destinations)
- Reject or sanitize unexpected characters
- Implement length limits to prevent header overflow
Monitor and Test
Verify your fixes and enable detection:
- Test with CRLF injection payloads:
%0d%0aSet-Cookie:admin=true,\r\nLocation:http://evil.com - Test header splitting:
value\r\nX-Injected-Header:malicious - Test response splitting:
\r\n\r\n<script>alert(1)</script> - Log all header values and alert on suspicious patterns
- Verify the specific input that triggered the finding no longer causes the vulnerability
- Ensure legitimate functionality still works correctly (e.g., redirects)
- Re-scan with the security scanner to confirm the issue is resolved
Common Vulnerable Patterns
- Directly inserting untrusted data into HTTP headers
- Failing to validate or encode header values
Unsanitized User Input in HTTP Header (Pseudocode)
Secure Patterns
CRLF Sanitization for HTTP Headers (Pseudocode)
# Safe: remove CR/LF from input
clean_input = user_input.replace('\r', '').replace('\n', '')
response.headers['Location'] = clean_input
Why this works:
- Removes carriage return (
\r) and line feed (\n) characters that terminate HTTP headers - Prevents attackers from injecting additional headers or response body content
- Blocks HTTP response splitting attacks that enable XSS, cache poisoning, or session fixation
- Ensures user input cannot break out of the intended header value context
- Combined with proper URL validation, prevents malicious redirects with injected headers
Language-Specific Guidance
For detailed, framework-specific code examples and patterns, see:
- Python - Flask, Django, FastAPI examples with CRLF sanitization
- Java - Spring Boot, Servlets with header validation
- JavaScript/Node.js - Express, Koa, Next.js with URL and header sanitization
- C# - ASP.NET Core with header security