HTTP Header Injection
Author: HollyGraceful Published: 06 August 2021 Last Updated: 03 November 2022
HTTP Header Injection vulnerabilities occur when user input is insecurely included within server responses headers. Specifically they are based around the idea that an attacker can cause the server to generate a response which includes carriage-return and line-feed characters (or %0D and %0A respectively in their URI encoded forms) within the server response header the attacker may be able to add crafted headers themselves. Header Injection can allow for attacks such as response splitting, session fixation, cross-site scripting, and malicious redirection.
That is to say that generally the injection of headers itself is not the final attack but it’s simply one way of being able to access, or exploit, another issue. For example a site which is vulnerable to Cross-site Scripting in the Referer header or in a cookie value could be attacked if an attacker is able to inject a payload through HTTP header injection.
Generally an attack would be performed by generating a URL which includes these characters and the vulnerable server would embed them within the response. For example, take the following URL and response:
HTTP/1.1 302 Object moved Date: Mon, 07 Mar 2016 17:42:46 GMT Location: account.asp?origin=foo Connection: close Content-Length: 121 <head><title>Object moved</title></head> <body><h1>Object Moved</h1>This object may be found <a HREF="">here</a>.</body>
We can see here that the origin parameter is included within the response headers. Now if that parameter accepts carriage-return/line-feeds we could get header injection. In this case it would, for example, be possible to inject headers such as the Set-Cookie header to cause the browser to create a cookie with chosen content – to allow us, for example, to exploit a session fixation vulnerability. Like this:
This request would result in something like the following:
HTTP/1.1 302 Object moved Connection: close Location: account.asp?origin=foo Set-Cookie: ASPSESSIONID=SessionFixed Content-Length: 121
<head><title>Object moved</title></head> <body><h1>Object Moved</h1>This object may be found <a HREF="">here</a>.</body>
Here we’ve added a malicious cookie which will be set in the victim’s browser. In this context it would be unlikely for us to be able to get a malicious redirect as our payload is injected beneath the legitimate Location header and since we’re injecting into a 302 response it’s unlikely that we’ll be able to get Cross-site Scripting here by breaking into the page body through double CRLFs (%0d%0a%0d%0a). As you can imagine – your options for exploitation vary depending on the type of response you’re injected into and also where in the response you’re placed!
In any response it’s likely that you can set a cookie. In a 302 above the Location header you may be able to cause a malicious redirect and within a 200 OK you could potentially set a cookie, deface the web application, redirect the user or cause a cross-site scripting style attack!
Testing for HTTP header injection is simple with a tool like Burp Suite, where you can use the “Repeater tool” which is what I was working on to generate these example requests and responses! Like this:
Generally it’s a bad idea to allow user input into the server response headers, but if it’s required the ensure that all carriage-return and line-feed characters (and all of their encoded variants) and appropriately filtered out to prevent attacks of this nature.