What is HTTP Response Splitting?
HTTP response splitting is a form of web application vulnerability, resulting from the failure of the application or its environment to properly sanitize input values. It can be used to perform cross-site scripting attacks, cross-user defacement, web cache poisoning, and similar exploits.
The attack consists of making the server print a carriage return (CR, ASCII 0x0D) line feed (LF, ASCII 0x0A) sequence followed by content supplied by the attacker in the header section of its response, typically by including them in input fields sent to the application. Per the HTTP standard (RFC 2616), headers are separated by one CRLF and the response’s headers are separated from its body by two. Therefore, the failure to remove CRs and LFs allows the attacker to set arbitrary headers, take control of the body, or break the response into two or more separate responses—hence the name.
The Web Application Security Consortium also has a good writeup, including sources with more details.
How Did The Vulnerability Work?
Reddit.com, like many sites on the Internet, has a redirect system built into its login functionality. If you’re viewing a page on reddit.com and choose to log in, the system will redirect you back to your original page afterward. The redirect functionality appears to be limited to pages on reddit.com and to reddit.com subdomains.
Under normal circumstances, a login URL with a redirect might look
something like this:
If a user is already logged in, that URL will skip the login step and go straight to the redirection. The headers sent for that redirect look like this:
1 2 3 4 5 6 7 8 9 10 11
HTTP/1.1 302 Moved Temporarily Content-Type: text/html; charset=UTF-8 Location: /r/reddit.com Pragma: no-cache Cache-Control: no-cache Content-Encoding: gzip Content-Length: 20 Server: '; DROP TABLE servertypes; -- Vary: Accept-Encoding Date: Fri, 14 Jan 2011 03:02:59 GMT Connection: keep-alive
Unfortunately, the vulnerability occurred because the “dest” parameter of the URL allowed an attacker to include newline characters (\r\n, or %0D%0A). Those characters were then parsed literally, which gave an attacker control over part of the HTTP response being sent by reddit’s servers.
To illustrate the point, lets take a look at one of the proof of concepts I developed to demonstrate the vulnerability.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
Proof of Concepts
I developed a number of proof of concepts, since browser-specific behaviors heavily influenced whether a particular URL could trigger an XSS vulnerability in a particular browser.
This proof of concept worked in both Firefox and Chrome. Both browsers would not redirect and would display the body of the response if the Location header contained a null byte.
And of course, no XSS writeup would be complete without a picture. So, here’s a screenshot of the first proof of concept in action:
In case anyone is curious, this vulnerability was patched within 48 hours of my original report.
I want to thank reddit’s admins for supporting the responsible disclosure of security vulnerabilities.
Also, if you have any questions about HTTP Response Splitting or other web application security vulnerabilities, feel free to leave them in the comments!