According to the OWASP, the attack HTTP response splitting
is a means to an end, not an end in itself - that is, it is a gap used to carry out other types of attack. 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 unreliable source, most often it is an HTTP request.
- 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 entry that contains CR characters (Carriage, Return, represented by %0d
or \r
) and LF (line feed, represented by %0a
or \n
) in the header and the underlying platform shall 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 app 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 on the pertinent issues I found in https://security.stackexchange.com/search?q=HTTP+Response+Splitting (Security-oriented Stack Exchange community) almost all are not necessarily an attack. But some have in common the fact that they use loopholes in proxy
and not necessarily the web server itself, so it is 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 of Java, but this problem has been fixed on virtually all modern Java EE application servers. If you are concerned about this risk, you should test on the worry platform 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 formed from non-validated user input I can change my user name '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 configure the username
for 'João r n r r r r r r r r r r r r r r r r r r r r r r r n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n n:
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 a Javascript code was injected into the page. This is a form of XSS/DOM injection through the attack of "splitting" but not necessarily a HTTP response splitting
, but uses 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 r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r r... ", the HTTP response would be divided into an imposter response followed by the 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 CRLF characters through 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 by doing a test like this in your application, and it is possible to see the Alert your system is vulnerable to CRLF injection, then vulnerable to HTTP response splitting
.
The attacker’s ability to build HTTP responses by using HTTP response splitting
, allows several other resulting attacks, including: Cross-User Defacement, Cache Poisoning, Cross-site Scripting (XSS) and Page Hijacking.
It’s not really an answer to all your questions, but it’s still a header injection. Only happens if you use some value typed by the user in a header untreated. That is, it is a security issue at the application level. The risk is to allow an attacker to return what they want using a endpoint your. On your last question, I believe this should be dealt with at the application level and not directly on the server. It is the responsibility of your application to treat the headers, potentially with URL encoding.
– Anthony Accioly