safety – What is HTTP response splitting?

Question:

Reading about HTTP headers I came across a filter function that removed both invalid characters from the header field value and multiple CRLF characters. This second on the pretext of avoiding HTTP response splitting . From what I understand superficially, this attack consists in you setting the value of the field containing at least two CRLF and in this way having full control of the request body.

For example:

Fake: foo\r\n\r\nHello world

This header field would be interpreted as:

Fake: foo

Hello world

Where, then, Hello world would be interpreted as the request body due to the blank line separating the content headers, see HTTP specification. Or better, if the HTTP response has something like:

HTTP/1.1 200 OK
Fake: foo\r\n\r\nHTTP/1.1 200 OK\r\n\r\nHello World

It will be interpreted as:

HTTP/1.1 200 OK
Fake: foo

HTTP/1.1 200 OK

Hello World

That is, two distinct HTTP responses, which define the name response splitting .

  • Is HTTP response splitting really that or did I get it wrong?
  • What would be the risks for the application not to address this vulnerability?
  • Servers, like Apache and Nginx, already have some kind of security against this?

If possible, give examples of requests that make use of HTTP response splitting to take advantage of the server's vulnerability.

Answer:

According to OWASP , the HTTP response splitting attack is a means to an end, not an end in itself – that is, it is a loophole used to carry out other types of attacks. 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.

"HTTP response splitting" occurs when:

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

To mount a successful attack, the application must allow input containing CR (carriage return, represented by %0d or \r ) and LF (line feed, represented by %0a or \n ) characters in the header and the underlying platform it must be vulnerable to the injection of such characters. These characters not only give attackers control of the remaining headers and the body of the response the application intends to send, but also allow them to create additional responses under their control.

I believe that, in general, this vulnerability has been fixed on most modern application servers, regardless of the language in which the code was written. At least the pertinent questions I found at https://security.stackexchange.com/search?q=HTTP+Response+Splitting (Security-focused Stack Exchange Community) almost all are not necessarily an attack. But some have in common the fact that they use proxy loopholes and not necessarily the web server itself, so it's still possible that these attacks occur today.

If you are concerned about this risk you should test on your current platform whether it allows CR or LF characters to be injected into headers. The example below uses an example from Java, but this issue has been fixed in virtually all modern Java EE application servers. If you are concerned about this risk, you should test on the platform of concern to see if the underlying platform allows CR or LF characters to be injected into headers.

For a practical example, let's take the request:

 HTTP/1.1 200 OK
 Date: Thu, 13 Jul 2017 02:02:45 GMT
 Last-Modified:Mon, 10 Jul 2017 21:30:06 GMT
 Accept-Ranges:  none
 Connection: close
 Content-Type: text/html; charset=UTF-8
 Cookie: test=114&username=João

 <html>
 [...]

However, as the cookie value is made up of unvalidated user input I can change my username 'John' and include CRLF (as explained above) in the field. An attacker could then inject malicious content into the page, for example, it would be possible to set the username to 'John\r\n\r\nmalicious content … `, which would result in the following HTTP response:

 HTTP/1.1 200 OK
 Date: Thu, 13 Jul 2017 02:02:45 GMT
 Last-Modified:Mon, 10 Jul 2017 21:30:06 GMT
 Accept-Ranges:  none
 Connection: close
 Content-Type: text/html; charset=UTF-8
 Cookie: test=114&username=João

 <script>conteúdo malicioso ... </script>
 <html>
 ...

In this example JavaScript code has been injected into the page. This is a form of XSS/DOM injection through the "splitting" attack but not necessarily an HTTP response splitting , but using the same technique to inject some malicious code into the page.

Let's now for example change the malicious code to something like "John\r\n\r\nContent-Length: 45\r\n\r\nmalicious content…", the HTTP response would be split into an imposter response followed by original answer, which is now ignored:

 HTTP/1.1 200 OK
 Date: Thu, 13 Jul 2017 02:02:45 GMT
 Last-Modified:Mon, 10 Jul 2017 21:30:06 GMT
 Accept-Ranges:  none
 Connection: close
 Content-Type: text/html; charset=UTF-8
 Cookie: test=114&username=João
 Content-Length: 45

 <html>conteúdo malicioso ... </html>
 <html>conteúdo original começa após o 46º caracter e é ignorado.[...]

On an unprotected server you could send the CRLF characters via the querystring:

http://www.yoursite.com/somepage.php?page=%0d%0aContent-Type: text/html%0d%0aHTTP/1.1 200 OK%0d%0aContent-Type: text/html%0d%0a%0d%0a%3Cscript%3Ealert(1)%3C/script%3E

The client would see the result of the script, which in this case is a simple alert:

<script>alert(1)</script>    

If when doing a test like this in your application, and you can see the alert your system is vulnerable to CRLF injection, therefore vulnerable to HTTP response splitting .

The attacker's ability to construct split HTTP response splitting with HTTP response splitting allows for several other resulting attacks, including: Cross-User Defacement , Cache Poisoning , Cross-site Scripting (XSS) and Page Hijacking .

Scroll to Top