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.

HTTP response splitting occurs when:

    . Data enters a web application through an untrusted source, most frequently 
      an HTTP request.
    . The data is included in an HTTP response header sent to a web user without 
      being validated for malicious characters. 

HTTP response splitting is a means to an end, not an end in itself. At its root, the attack is straightforward: an attacker passes malicious data to a vulnerable application, and the application includes the data in an HTTP response header.

To mount a successful exploit, the application must allow input that contains CR (carriage return, also given by %0d or \r) and LF (line feed, also given by %0a or \n)characters into the header. These characters not only give attackers control of the remaining headers and body of the response the application intends to send, but also allow them to create additional responses entirely under their control.

Examples

The following code segment reads the name of the author of a weblog entry, author, from an HTTP request and sets it in a cookie header of an HTTP response.

        String author = request.getParameter(AUTHOR_PARAM);
        ...
        Cookie cookie = new Cookie("author", author);
            cookie.setMaxAge(cookieExpiration);
            response.addCookie(cookie);

Assuming a string consisting of standard alpha-numeric characters, such as "Jane Smith", is submitted in the request the HTTP response including this cookie might take the following form:

        HTTP/1.1 200 OK
        ...
        Set-Cookie: author=Jane Smith
        ...

However, because the value of the cookie is formed of unvalidated user input, the response will only maintain this form if the value submitted for AUTHOR_PARAM does not contain any CR and LF characters. If an attacker submits a malicious string, such as "Wiley Hacker\r\nHTTP/1.1 200 OK\r\n...", then the HTTP response would be split into two responses of the following form:

        HTTP/1.1 200 OK
        ...
        Set-Cookie: author=Wiley Hacker

        HTTP/1.1 200 OK
        ...

Clearly, the second response is completely controlled by the attacker and can be constructed with any header and body content desired. The ability of the attacker to construct arbitrary HTTP responses permits a variety of resulting attacks, including: Cross-User Defacement, Cache Poisoning, Cross-site Scripting (XSS) and Page Hijacking.

Cross Site scripting – Through response splitting

I’d like to point out here that I’m not explaining Cross Site Scripting and its types in great detail over here. There are plenty of great articles available online (I’ll link a few in the References section) that you can read to gain further clarity on the same.

Now that we’re reasonably clear about what Response Splitting is, can we take this one step forward from an attacker’s perspective. Can we, through response splitting, run Javascript on a victim machine and try and eventually gain complete control of his browser? Yes, we can, by just extending the example that we took earlier a little bit further..

If you remember, the second malicious response that we’d crafted above was a simple HTML page which said that the user had been phished. Instead of the simple HTML page, we would have to write some Javascript code instead. Instead of a simple HTML page that gets displayed, the Javascript would run instead on the user’s browser.

Control that the attacker will have over the user’s browser will depend completely on the Javascript code that was written. So for e.g .. Extending the same example which we discussed earlier in this article, the URL that the attacker would craft would be something like this:

     http://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.
     1%20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0aalert
     ('Running JS on your machine')

He would then send a request for branches.html like before and it would get mapped to this second response which contains malicious Javascript. The proxy cache will get poisoned like before and when a user who sits behind this proxy accesses branch.html – the JS will run on his machine.

In case there is a parameter that is vulnerable to XSS on the target site, the same logic can be used to exploit that as well. Only, in this case there’ll be a script in the vulnerable parameter, which is part of a request and not Javascript in the body of the HTML page as above.

The Javascript in this example is extremely straightforward and will only pop up a little alert box. However there can be more complex JS that can be written which can result in an attacker gaining complete control of a user’s browser and eventually, control of the user’s machine as well.

An exploitation framework called BeeF is of great help to the attacker here, if he wants to do this. He will just have to write a little Javascript and point it to the BeeF controller which will be installed on some machine which is reachable from the victim.

Cross Site Request Forgery – Through Response Splitting

Again, I’m not diving very deep into how the CSRF attack works. You can take a look at the references I provide for further details about the same. In a nutshell though, a person who is a victim to a CSRF attack, will perform a ‘non-view’ operation unknowingly.Note that this is an operation that he wouldn’t have otherwise performed.

The pre-requisites for a CSRF attack to happen are that the victim needs to be logged in to the site for which the oepration is to be performed. So if the operation that the attacker wants to trick the user into performing is a ‘Delete my Google Profile’, the user will have to be logged into Google’s systems, when the operation is performed.

Secondly, the attacker must be able to predict the exact structure of the request including the parameter values. So for e.g A fund transfer request would look like GET /transfer/php?acc1=1000&acc2=2000&amt=900. If a user sends a GET request like mentioned, while being logged in to www.abc.com , a fund transfer will automatically happen from acc1 to acc2.

In a CSRF attack, the attacker somehow tricks the user to click that link using Social Engineering techniques or gets the user to visit a page under the attacker’s control, where this request is performed in the background, transparent to the user.

Now, back to Response Splitting, you’ll remember that the attacker used Response Splitting to poison the page branches.html and insert malicious Javascript into the page to attempt to run scripts on the user’s browser. In the case of CSRF you will need to ensure that the action (fund transfer URL) is automatically performed when the user accesses the poisoned page.

So in other words, branches.html can contain a small image which automatically loads each time the page loads. The tag of this image though will send a request – /transfer/php?acc1=1000&acc2=2000&amt=900 to the www.abc.com server.

So the entire malicious URL, while performing response splitting will be as follows:

     http://www.abc.com/index.php?lang=german%0d%0aContent- Length:%200%0d%0aHTTP/1.1
     %20200%20OK%0d%0aContent-Type:%20text/html%0d%0aContent- Length:%20%0d%0a< / 
     body>< / html>

So whenever the user behind the proxy visits the poisoned page(branches.html) and he’s signed in to www.abc.com in another tab, the operation will succeed in the background and funds will be transparently transferred to the attacker’s account.

Mitigation:

    Response Splitting:- Use server side validation and disallow CRLF characters 
    in all requests where user input is reflected in the response header.

    XSS: White List and Black List filtering(Input Validation), Escape HTML
    (Output Validation).

    CSRF:Use AntiCsrf tokens so that the attacker cannot predict the exact 
    structure of the request to forge.

Conclusion:

A response splitting attack is possible only if there is a proxy server which multiple users use to connect to various websites. The cache of the proxy server is poisoned and the user becomes a victim whenever the proxy cache serves that page.