HTTP Response Splitting

What is HTTP response splitting?

In a HTTP Response Splitting attack an attacker exerts control over the response sent by a website to a user in such a way that the user's browser interprets the response as two separate web pages (i.e. two separate HTTP responses). This can allow an attacker to perform cross-site scripting, webpage defacement, and to hijack pages with confidential user information.

The attacker splits the website's response by inserting characters which ends the first response and starts a new one. The attacker will be able to control part of the first response. More significantly he will have complete control over the second response. To launch the attack, the attacker must induce the user’s browser to make two requests to the web server. The first request performs the splitting, generating two web pages in response. The second request will then be matched to the second of the response pages (instead of the actual page requested). Thus attacker can deliver a page to the user which, instead of being that expected, is a page fully controlled by the attacker. Estimates suggest at least 1 out of 25 sites are vulnerable to HTTP Response Splitting attacks.

What makes a site vulnerable?

The attack is possible on websites which generate raw HTTP responses explicitly, and incorporate inadequately validated user input into them. This allows an attacker to insert characters which terminate one HTTP response and start a new one.

Impact of the attack

On vulnerable sites HTTP response splitting can be used to conduct cross-site scripting (XSS) in the second response (and possibly in the first). As a result, all the potential dangers associated with XSS attacks also apply to HTTP response splitting. There are other dangers specific to HTTP response splitting. The attack can be used to ‘poison’ web pages stored in cache servers (i.e. replace legitimate pages with attacker-specified pages). This can allow the attacker to influence the pages seen by many users. The problem is particularly bad if the website routes all webpages through its own cache server. In such cases, a single exploit may allow the attacker to replace all pages in the cache and thereby deny users access to legitimate content.

From: here
"One thing that came up (that I had known about for a while, but for some reason it's just not been made super public yet) was some of the work Arian Evans has been doing with HTTP Response splitting. When he started working with it he realized that he was inadvertantly taking out huge chunks of the site with his own content. After some debugging he realized he was hitting caching servers (a la Amit Klein’s work). But there are two nasty things about that that go above and beyond what we knew before.

The first is that it can re-write the caching headers, so that instead of a 5 minute time-out like you intended for your caching server to use, it can be upped to months or years, causing a much larger problem. The second is that is not a one to one, but a one to many relationship. That is, you can take over pages that are well beyond the reach that you normally have - including pages you don’t technically have access to, which can potentially give you access to anything under any user (ultimate persistent XSS). Super nasty! So yah, I wasn’t sure how quiet that was, but Arian finally let the cat out of the bag, so there it is."

HTTP response splitting example

An example of a webpage which is vulnerable to HTTP response splitting is a redirect script, as follows:

<?php header('location:'.$_GET['page']); ?>

Since the page variable is entered without validation into a HTTP response header, the attacker can insert a sequence of CR and LF characters in order to end the current HTTP response and start a new one. This type of redirect is seen on many sites which use it, for instance, to record clicks on outgoing links on those sites.

Preventing HTTP response splitting

To prevent HTTP response splitting, web-application developers should:

Preventing HTTP response splitting examples

As examples of how to prevent HTTP response splitting, consider how we might rewrite the example code from above. First, suppose we only allow redirections to a pre-determined set of webpages. We can now simply check that the requested redirect page is a permitted webpage:

<?php 
$page = $_GET['page'];
if ($page=='http://www.google.com' or $page=='http://www.example.com/page.php')
	header('location:'.$page); 
else exit();
?>

But what if we don't know in advance what pages we will allow redirections to? If we knew of a set of permitted pages, we could perhaps craft a regular expression which matches only those pages. But if we regularly link to many pages, even this may be impractical. In such cases, to prevent HTTP response splitting we can just check that the requested URL only contains safe characters. For example:

<?php 
$page = $_GET['page'];
if (!preg_match('/[^0-9a-zA-Z\/ \-_()\[\]+\.!&£$%?:;=]/', $page))
	header('location:'.$page); 
else exit();
?>

You may need to allow other characters as appropriate, but careful consideration should be given to their impact. New line and carriage return characters should never be allowed.

Warning: Never use this code in a production website. While it protects against HTTP response splitting, it is vulnerable to other problems such as being an open redirector which can be used to coerce a site into attacking other sites.