Listen to this Post

Introduction:
A decades-old vulnerability class, stemming from inconsistent newline handling in HTTP/1.1, remains a potent threat to modern web applications. This security flaw, famously detailed in Michal Zalewski’s The Tangled Web, can be exploited to perform response header injection, allowing attackers to set arbitrary cookies, manipulate redirects, and poison caches on misconfigured servers that haven’t yet adopted HTTP/2.
Learning Objectives:
- Understand the fundamental cause of HTTP header injection vulnerabilities in HTTP/1.1.
- Learn to identify and audit vulnerable Nginx configuration patterns.
- Acquire the skills to mitigate this risk through secure configuration and protocol enforcement.
You Should Know:
1. The Core Vulnerability: Newline Characters in URLs
The exploit hinges on the interpretation of URL-encoded newline characters. In HTTP/1.1, headers are separated by a Carriage Return Line Feed (CRLF) sequence, represented as `%0d%0a` in URL encoding. If a server incorrectly decodes user input containing these sequences and reflects them into response headers, it can allow an attacker to break out of the header value and inject entirely new headers.
2. Identifying a Vulnerable Nginx Redirect Configuration
A common vulnerable pattern in Nginx involves using the `$uri` or `$document_uri` variable within a `Location` block for a redirect. These variables contain the normalized URL-decoded request URI. If the normalization process doesn’t strip CRLF characters, they are passed directly into the redirect response.
Vulnerable Configuration Example:
server {
listen 80;
server_name example.com;
error_page 404 = @redirect;
location @redirect {
return 302 https://example.com$uri;
}
}
Step-by-step guide: This configuration is intended to redirect 404 errors. However, by requesting a URL like https://example.com/%0d%0aSet-Cookie:malicious=payload`, the `$uri` variable becomes `/` followed by the CRLF sequence and the fake header. When Nginx constructs the `Location` header, it becomesLocation: https://example.com/%0d%0aSet-Cookie:malicious=payload`. The HTTP protocol interprets the `%0d%0a` as a header terminator, and the `Set-Cookie:` string is processed as a new, valid header by the client’s browser.
3. Exploitation Proof-of-Concept Command
You can test for this vulnerability using `curl` to inspect the raw response headers.
Command:
curl -I -H "Host: example.com" "http://<TARGET_IP>/%0d%0aSet-Cookie:%20injected=value"
Step-by-step guide: This command sends an HTTP HEAD request (-I) to the target. The URL includes the malicious payload %0d%0aSet-Cookie:%20injected=value. If the server is vulnerable, the response will include your injected `Set-Cookie: injected=value` header alongside the server’s normal headers. The `-H “Host: example.com”` header may be necessary if testing against an IP address.
4. Mitigation 1: Using the $request_uri Variable
The primary mitigation is to replace the vulnerable `$uri` variable with the `$request_uri` variable in redirects. `$request_uri` contains the original, un-normalized request URI, including any percent-encoded characters. This prevents the decoding of `%0d%0a` into active CRLF control characters.
Secure Configuration:
location @redirect {
return 302 https://example.com$request_uri;
}
Step-by-step guide: With this configuration, a request to `/%0d%0aSet-Cookie:foo=bar` will result in a `Location` header of `https://example.com/%0d%0aSet-Cookie:foo=bar`. The CRLF sequences remain URL-encoded and are treated as literal part of the URL string, not as control characters, neutralizing the injection.
5. Mitigation 2: Enforcing HTTP/2 and H2C
The HTTP/2 protocol fundamentally eliminates this threat by using a binary framing layer for transmission. Headers are compressed and sent in dedicated frames, completely removing the textual, newline-delimited format that is the root cause of CRLF injection attacks.
Nginx Configuration to Enforce HTTP/2:
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/private/key.pem;
...
}
Step-by-step guide: Adding the `http2` parameter to the `listen` directive tells Nginx to use HTTP/2 for all connections on this port. This requires SSL/TLS termination. For internal or upstream services, you can use `http2` on a `listen` directive for a non-SSL port to enable HTTP/2 over plain text (H2C), though this is less common.
6. Advanced Mitigation: Web Application Firewall (WAF) Rules
For defense-in-depth, a WAF can be configured to block requests containing malicious patterns associated with header injection attempts.
ModSecurity Rule Example:
SecRule REQUEST_URI|REQUEST_HEADERS "@rx (?:\%0a|\%0d|\n|\r)" \ "id:100000,phase:1,deny,log,msg:'CRLF Injection Attack Attempt',t:urlDecode"
Step-by-step guide: This rule inspects the request URI and headers for URL-encoded (%0a, %0d) or literal (\n, \r) newline characters. The `t:urlDecode` transformation function decodes the request before applying the regex check, ensuring it catches encoded payloads. If a match is found, the request is denied and logged.
7. Automated Scanning with Nuclei
The open-source tool Nuclei has templates specifically designed to detect CRLF injection vulnerabilities across a wide range of targets.
Scan Command:
nuclei -u https://target.example.com -t http/header-injection/crlf-injection.yaml
Step-by-step guide: This command runs the `crlf-injection.yaml` template against the target URL. Nuclei will automatically craft malicious requests with various CRLF payloads and analyze the responses for evidence of successful header injection, providing a quick and automated way to audit your application surface.
What Undercode Say:
- Key Takeaway 1: Technical debt has a direct security cost. The persistence of HTTP/1.1, combined with common configuration oversights, keeps old vulnerabilities alive and well in modern infrastructure.
- Key Takeaway 2: Assumptions about input sanitization are dangerous. The vulnerability arises from a subtle interaction between URL decoding and header construction—a blind spot that persists because the variables (
$urivs.$request_uri) appear functionally identical to many engineers.
This incident is a stark reminder that foundational protocol knowledge is non-negotiable for security and operations teams. While the industry rushes toward zero-trust and AI-powered security, a simple misconfiguration from a decade-old handbook can still compromise a system. The mitigation is simple, but the discovery requires understanding the “why” behind the rule. This reinforces the principle that secure configuration must be proactive and rooted in a deep understanding of the underlying technology, not just checklist compliance.
Prediction:
The long-tail adoption of HTTP/2 and HTTP/3 will ensure that this class of vulnerability remains relevant for at least another decade, particularly in legacy enterprise systems and IoT devices. However, we predict a shift in exploitation. While basic cookie injection will persist, advanced attackers will increasingly weaponize CRLF chains for more sophisticated attacks like HTTP Request Smuggling (HRS) to bypass security controls, poison reverse proxy caches, and achieve blind Server-Side Request Forgery (SSRF). Automated scanners will increasingly incorporate these hybrid attack sequences, moving the threat from a manual, targeted exploit to a scalable, automated one.
🎯Let’s Practice For Free:
IT/Security Reporter URL:
Reported By: Zak Fedotkin – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


