HTTP Response Splitting

HTTP Response Splitting is a powerful new attack technique that enables other attacks.


August 01, 2004
URL:http://www.drdobbs.com/security/http-response-splitting/184405766

August, 2004: HTTP Response Splitting

Dealing with a new, powerful intruder attack

Steve is CTO of Sanctum and participates in several working groups of the Internet Engineering Task Force (IETF) and Web Application Security Consortium (WASC). He can be contacted at sorrinsanctuminc.com. Amit is Director of Security and Research for Sanctum. He can be contacted at aklein sanctuminc.com.


In the process of developing AppScan (a security testing tool from Sanctum, the company we work for), we discovered a new attack technique called "HTTP response splitting." This powerful and elegant technique has an impact on various web environments. HTTP response splitting enables various attacks, such as web-cache poisoning, cross-user defacement, page hijacking of user information, and cross-site scripting (XSS). HTTP response splitting—and the attacks derived from it—is relevant to most web environments and is the result of an application's failure to reject illegal user input; in this case, input containing malicious or unexpected characters—the CR and LF characters.

An HTTP response-splitting attack always involves at least three parties:

At the heart of HTTP response splitting is the attacker's ability to send a single HTTP request that forces the web server to form an output stream, which is then interpreted by the target as two HTTP responses instead of the normal single response. The first response may be partially controlled by attackers, but this is less important. What is material is that attackers completely control the form of the second response from the HTTP status line to the last byte of the HTTP response body. Once this is possible, attackers realize the attack by sending two requests through the target. The first one invokes two responses from the web server, and the second request typically is to some "innocent" resource on the web server. However, the second request is matched by the target to the second HTTP response, which is fully controlled by attackers. Attackers, therefore, trick the target into believing that a particular resource on the web server (designated by the second request) is the server's HTTP response (server content) while, in fact, it is some data that is forged by attackers through the web server—this is the second response.

HTTP response-splitting attacks occur where the server script embeds user data in HTTP response headers. This typically happens when the script embeds user data in the redirection URL of a redirection response (HTTP status code 3xx), or when the script embeds user data in a cookie value or name when the response sets a cookie. In the first case, the redirection URL is part of the Location HTTP response header, and in the second cookie setting case, the cookie name/value is part of the Set-Cookie HTTP response header.

For instance, consider the JSP page (located in /redir_lang.jsp) in Example 1(a). When invoking /redir_lang.jsp with a parameter lang=English, it redirects to /by_lang.jsp?lang=English. Example 1(b) is a typical response (the web server is BEA WebLogic 8.1 SP1). As you can see, the lang parameter is embedded in the Location response header. In terms of mounting an HTTP response-splitting attack, instead of sending the value English, we send a value that makes use of URL-encoded CRLF sequences to terminate the current response and shape an additional one. Example 2(a) illustrates how this is done. This results in the output stream in Example 2(b), sent by the web server over the TCP connection. This TCP stream is parsed by the target as follows:

  1. A first HTTP response, a 302 (redirection) response.
  2. A second HTTP response, a 200 response with content comprising of 19 bytes of HTML.
  3. Superfluous data. Everything beyond the end of the second response is superfluous and does not conform to the HTTP standard. So when attackers feed the target with two requests, the first being to the URL in Example 3(a) and the second to the URL in Example 3(b), then the target would believe that the first request is matched to the first response; see Example 3(c). And by this, the attacker manages to fool the target.

Admittedly, this example is naive. For instance, it doesn't take into account problems with how targets parse the TCP stream, issues with the superfluous data, problems with the data injection, and how to force caching.

Security Impact

With HTTP response splitting, it is possible to mount various kinds of attacks:

A Step Toward the "Perfect Hack"

One of the unique properties of HTTP response-splitting's web-cache poisoning attack is its forensics and incident-response hampering qualities. Typically, when a site is defaced or hacked, site administrators are notified by unhappy users. In classic examples of web-site defacement where a file on the web server itself has been altered or replaced, a quick look at the site by the administrator is all that is necessary to validate that the attack has occurred. With web-cache poisoning, the altered or replaced page will not show up on the web server and may be invisible to internal employees accessing the site directly as opposed to accessing it from the external Internet (where the cache server typically provides its service). Further, in the instance of an intermediate web-cache server attack, such as an online service or ISP's cache servers, administrators will be unable to verify the attack unless they are accessing the site via the ISP or online service. Web-cache poisoning can also result in insufficient logs. Due to the transient nature of the data held in cache servers, pages cached and the time of cache refresh or update are rarely logged, and even if the time of update is logged, the page content is not. This also impedes incident response and forensics.

Finally, HTTP response splitting is reversible by attackers, who have the ability to undo the web-cache poisoning attack by submitting the injection with a payload constructed to reverse the effects. This is important on two key levels:

Recommendations

It is critical that web-application developers validate input. You need to remove CRs and LFs (and all other hazardous characters) before embedding data into any HTTP response headers, particularly when setting cookies and redirecting. Another option is to reject requests that contain these characters in data that is embedded into HTTP headers, as such requests are attack attempts. It is possible to use third-party products (like Sanctum's AppShield, for example) to prevent CR/LF injection.

Consider the (vulnerable) J2EE script example from Example 1(a), in which the code was shown to be vulnerable (at least, in BEA WebLogic 8.1 SP1 and in IBM WebSphere 5.1 servers). It can be easily fixed by making sure that no CR/LF is present in the parameter; see Example 4. This logic ensures that the lang parameter does not contain any CR or LF by searching for each and ascertaining that neither is found in the parameter value.

In ASP.NET, making sure that controls do not contain specific characters amounts to using (correctly) the regular expression field validator. For example:

<asp:RegularExpressionValidator
ControlToValidate=
"lang " ValidationExpression="^[^\r\n]*$"
runat="server" id="..." />

This ASP.NET field validator is bound to the user-input control lang, and validates this input field by ensuring that it does not contain the CR/LF characters. This is done via matching the input field to a regular expression that does not allow any CR or LF in its pattern. Of course, it is also necessary to test explicitly for the state of the validator (by checking lang.IsValid or by checking the global page state Page.IsValid).

Furthermore, you should make sure to use the most up-to-date application engine and ensure that your application is accessed through a unique IP address (that is, that the same IP address is not used for another application as it is with virtual hosting).

Lastly, we advise that you scan the application (before deployment, using a tool such as Sanctum's AppScan, http://www.sanctuminc.com/) to ensure that the application is not vulnerable to HTTP response-splitting (and other) attacks.

Conclusion

HTTP response splitting is a new technique that enables several new and interesting attacks. This technique only applies to applications that do not validate their input before embedding it into HTTP response headers. Avoiding this vulnerability is a simple matter of adding a short If test (or, in ASP.NET, using a field validator control). Application programmers are encouraged to understand the new threat and to apply the simple security measures in their applications and, in general, to implement security (via input validation) in their code.

DDJ

August, 2004: HTTP Response Splitting

(a)

<%
response.sendRedirect("/by_lang.jsp?lang="+
request.getParameter("lang"));
%>


(b)
HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 12:53:28 GMT
Location: http://10.1.1.1/by_lang.jsp?lang=English
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT
2003 271009 with
Content-Type: text/html
Set-Cookie:
JSESSIONID=1pMRZOiOQzZiE6Y6iivsREg82pq9Bo1ape7h4YoHZ62RXjApqwB
E!-1251019693; path=/
Connection: Close

<html><head><title>302 Moved Temporarily</title></head>
<body bgcolor="#FFFFFF">
<p>This document you requested has moved temporarily.</p>
<p>It's now at <a
href="http://10.1.1.1/by_lang.jsp?lang=English">http://10.1.1.
1/by_lang.jsp?lang=English</a>.</p>
</body></html>

Example 1: (a) Typical JSP page; (b) typical response.

August, 2004: HTTP Response Splitting

(a)

/redir_lang.jsp?lang=foobar%0d%0aContent-
Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-
Type:%20text/html%0d%0aContent-
Length:%2019%0d%0a%0d%0a<html>Shazam</html>


(b)
HTTP/1.1 302 Moved Temporarily 
        Date: Wed, 24 Dec 2003 15:26:41 GMT 
        Location: http://10.1.1.1/by_lang.jsp?lang=foobar 
        Content-Length: 0 
         
        HTTP/1.1 200 OK 
        Content-Type: text/html 
        Content-Length: 19 
         
        <html>Shazam</html> 
        Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 
        2003 271009 with 
        Content-Type: text/html 
        Set-Cookie: JSESSIONID=1pwxbgHwzeaIIFyaksxqsq92Z0VULcQUcAanfK7In7IyrCST9Us 
        S!-1251019693; path=/ 
        Connection: Close 
        
        <html><head><title>302 Moved Temporarily</title></head> 
        <body bgcolor="#FFFFFF"> 
        <p>This document you requested has moved temporarily.</p> 
        [[[ truncated for brevity ]]] 

Example 2: (a) URL-encoded CRLF sequences to terminate the current response; (b) resulting output stream.

August, 2004: HTTP Response Splitting

(a)

/redir_lang.jsp?lang=foobar%0d%0aContent-
Length:%200%0d%0a%0d%0aHTTP/1.1%20200%20OK%0d%0aContent-
Type:%20text/html%0d%0aContent-
Length:%2019%0d%0a%0d%0a<html>Shazam</html>


(b)
/index.html


(c)
The following response is then matched to the second request for /index.html [Example 3(b)].
HTTP/1.1 302 Moved Temporarily
Date: Wed, 24 Dec 2003 15:26:41 GMT
Location: http://10.1.1.1/by_lang.jsp?lang=foobar
Content-Length: 0
And that the second request (to /index.html) is matched to the second response:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 19
<html>Shazam</html>

Example 3: Fooling the targets by feeding them multiple requests.

August, 2004: HTTP Response Splitting

String Lang=request.getParameter("lang");
    ...
    if ((Lang.indexOf('\r')==-1) && (Lang.indexOf('\n')==-1))
    {
        /* Lang does not contain CRs or LFs, so it's safe here */
        /* (at least from the perspective of                   */
        /* HTTP Response Splitting)                            */
        
        response.sendRedirect("/by_lang.jsp?lang="+Lang);
    }
   else
    {
        /* handle security error (reject the request) */

        ...
    }

Example 4: Eliminating CR/LFs from parameters.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.