HTTP response splitting is a form of HTTP header injection, the goal is to force the server to inject our own HTTP header in the response.
HTTP request or response are based on the same principle:
Where does the vulnerability appears then?
Imagine a website where you choose the language by selecting in a dropdownlist which post a Form toward the following PHP code:
header (“Location: /redirected?page=home&lang=” . $_POST[‘language’]);
If you select english for example, the response HTTP header you will receive will be like that:
HTTP/1.1 302 Found Content-Type: text/html Date: Fri, 23 Oct 2015 08:46:09 GMT Location: http://mywebsite.org/redirected?page=home&lang=en Content-Type: text/html Now imagine what will happens if instead of sending “en” in the language variable but something like:
en Content-Length: 0 HTTP/1.1 200 OK Content-Type: text/html Content-Length: 44 <html>hack response splitting attack</html>
Then the answer should be:
HTTP/1.1 302 Moved Temporarily Date: Fri, 23 Oct 2015 12:10:46 GMT Server: Apache-Coyote/1.1 Location: http://192.168.166.134/WebGoat/attack?Screen=3&menu=100&fromRedirect=yes&language=en%0AContent-Length%3A%200%0A%0AHTTP%2F1.1%20200%20OK%0AContent-Type%3A%20text%2Fhtml%0AContent-Length%3A%2041%0A%3Chtml%3E%3Cfont%20color%3Dred%3E%20hey%3C%2Ffont%3E%3C%2Fhtml%3E ...
and then the redirection will send to a page
HTTP/1.1 200 OK Date: Fri, 23 Oct 2015 12:10:46 GMT Server: Apache-Coyote/1.1 Pragma: No-cache Cache-Control: no-cache Expires: Wed, 31 Dec 1969 19:00:00 EST Content-Type: text/html
With the content
<html>hack response splitting attack</html>
So you have understood the principle but to use it in the real world, a few more information are needed.
In the above example, I have worked with a raw string but it should be URI encoded.
It means that every standard characters should be replaced by its HTML equivalent (rn become %0a %0d for example or ” ” space character become %20…) it is quite easy to find URI Encoder online, injection given above becomes:
Note: depending on the web server and the host OS, you may have to send “rn” (usually windows based) or just “r” (unix based) so you can tests both or perform some OS and web server fingerprint
So, you can say that it seems not to be too complex but not too useful as well for now.
HTTP Splitting with cache poisonning
Currently we are only attacking the computer we are on, not exactly the best goal.
We would like to cache the page we have inserted on the server.
To do so, we can use the HTTP Header “Last-Modified”, the purpose here is to know when the page has been modified lastly to check if the cache has already the latest version.
If the returned date is later than the one in current server cache or if the cache is not set for this page, it will be automatically added in the server cache.
So what if we set a date in the future?
en Content-Length: 0
HTTP/1.1 200 OK Content-Type: text/html Last-Modified: Fri, 27 Oct 2028 13:14:15 CET Content-Length: 44 <html>hack response splitting attack</html>
How to prevent this vulnerability?
To avoid such vulnerabilities, you must always parse user input for CR (r or %0a) and LF (n or %0d) characters. Please note that this vulnerability is not tied to a development language.
This recommendation is valid for a lot of vulnerabilities, never trust the end user, even if 99,99% of the usage are legit, you just need one with malicious intents to cause a huge ruckus…