|
HTTP Response Splitting
In the HTTP Response Splitting attack, there are always 3 parties (at
least) involved:
- Web server, which has a security hole enabling HTTP Response Splitting
- Target - an entity that interacts with the web server perhaps on behalf of
the attacker. Typically this is a cache server (forward/reverse proxy), or a
browser (possibly with a browser cache).
- Attacker - initiates the attack
The essence 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 one response, in the
normal case. The first response may be partially controlled by the attacker, but
this is less important. What is material is that the attacker completely controls the
form of the second response from the HTTP status line to the last byte of the
HTTP response body. Once this is possible, the attacker realizes the attack by
sending two requests through the target. The first one invokes two responses
from the web server, and the second request would typically be to some
"innocent" resource on the web server. However, the second request would be
matched, by the target, to the second HTTP response, which is fully controlled by
the attacker. The attacker, therefore, tricks 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 it is in fact some data, which is
forged by the attacker through the web server - this is the second response.
HTTP Response Splitting attacks take place 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.
The essence of the attack is injecting CRs and LFs in such manner that a second
HTTP message is formed where a single one was planned for by the application.
CRLF injection is a method used for several other attacks which change the data
of the single HTTP response send by the application (e.g. [2]), but in this case,
the role of the CRLFs is slightly different - it is meant to terminate the first
(planned) HTTP response message, and form another (totally crafted by the
attacked, and totally unplanned by the application) HTTP response message
(hence the name of the attack).
This injection is possible if the application (that runs on top of the web server)
embeds un-validated user data in a redirection, cookie setting, or any other
manner that eventually causes user data to become part of the HTTP response
headers.
With HTTP Response Splitting, it is possible to mount various kinds of attacks:
- Cross-site Scripting (XSS): Until now, it has been impossible to mount
XSS attacks on sites through a redirection script when the clients use IE
unless all the location headers can be controlled. This attack makes it
possible.
- Web Cache Poisoning (defacement): This is a new attack. The attacker
simply forces the target (i.e. a cache server of some sort - the attack was
verified on Squid 2.4, NetCache 5.2, Apache Proxy 2.0 and few other
cache servers) to cache the second response in response to the second
request. An example is to send a second request to
"http://web.site/index.html", and force the target (cache server) to cache the
second response that is fully controlled by the attacker. This is effectively a
defacement of the web site, at least as experienced by other clients, who
use the same cache server. Of course, in addition to defacement, an
attacker can steal session cookies, or "fix" them to a predetermined value.
- Cross User attacks (single user, single page, temporary defacement: As a
variant of the attack, it is possible for the attacker not to send the second
request. This seems odd at first, but the idea is that in some cases, the
target may share the same TCP connection with the server, among several
users (this is the case with some cache servers). The next user to send a
request to the web server through the target will be served by the target
with the second response the attacker generated. The net result is having
a client of the web site being served with a resource that was crafted by the
attacker. This enables the attacker to "deface" the site for a single page
requested by a single user (a local, temporary defacement). Much like the
previous item, in addition to defacement, the attacker can steal session
cookies and/or set them.
- Hijacking pages with user-specific information: With this attack, it is
possible for the attacker to receive the server response to a user request
instead of the user. Therefore, the attacker gains access to user specific
information that may be sensitive and confidential.
- Browser cache poisoning: This is a special case of "Web Cache
Poisoning" (verified on IE 6.0). It is somewhat similar to XSS in the sense
that in both the attacker needs to target individual clients. However, unlike
XSS, it has a long lasting effect because the spoofed resource remains in
the browser's cache.
Example
Consider the following JSP page (let's assume it is located in /redir_lang.jsp):
<%
response.sendRedirect("/by_lang.jsp?lang="+
request.getParameter("lang"));
%>
When invoking /redir_lang.jsp with a parameter lang=English, it will redirect to
/by_lang.jsp?lang=English. A typical response is as follows (the web server is
BEA WebLogic 8.1 SP1 - see section "Lab Environment" in [1] for exact details
for this server):
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=1pMRZOiOQzZiE6Y6iivsREg82pq9Bo1ape7h4YoHZ62RXj
ApqwBE!-1251019693; path=/
Connection: Close
302 Moved Temporarily
This document you requested has moved temporarily.
It's now at http://10.1.1.1/by_lang.jsp?lan
g=English.
As can be seen, the lang parameter is embedded in the Location response
header.
Now, we move on to mounting an HTTP Response Splitting attack. Instead of
sending the value English, we send a value, which makes use of URL-encoded
CRLF sequences to terminate the current response, and shape an additional
one. Here is how this is done:
/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%0aShazam
This results in the following output stream, sent by the web server
over the TCP connection:
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
Shazam
Server: WebLogic XMLX Module 8.1 SP1 Fri Jun 20 23:06:40 PDT 2003
271009 with
Content-Type: text/html
Set-Cookie:
JSESSIONID=1pwxbgHwzeaIIFyaksxqsq92Z0VULcQUcAanfK7In7IyrCST
9UsS!-1251019693; path=/
[...]
Explanation: this TCP stream will be parsed by the target as follows:
A first HTTP response, which is a 302 (redirection) response. This response is
colored blue.
A second HTTP response, which is a 200 response, with a content
comprising of 19 bytes of HTML. This response is colored red.
Superfluous data - everything beyond the end of the second response is
superfluous, and does not conform to the HTTP standard.
So when the attacker feeds the target with two requests, the first being to the
URL
/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%0aShazam
And the second to the URL
/index.html
The target would believe that the first request is matched to the first response:
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
Shazam
And by this, the attacker manages to fool the target.
Now, this particular example is quite nave, as is explained in [1]. It doesn't take
into account some problems with how targets parse the TCP stream, issues with
the superfluous data, problems with the data injection, and how to force caching.
This (and more) is discussed in [1], under the "practical consideration" sections.
Solution
Validate input. Remove CRs and LFs (and all other hazardous
characters) before embedding data into any HTTP response headers,
particularly when setting cookies and redirecting. It is possible to use
third party products to defend against CR/LF injection, and to test for
existence of such security holes before application deployment.
Further recommendations are:
Make sure you use the most up to date application engine
Make sure that your application is accessed through a unique IP address (i.e.
that the same IP address is not used for another application, as it is with virtual
hosting).
References
[1] "Divide and Conquer - HTTP Response Splitting, Web Cache Poisoning Attacks, and Related Topics" by Amit Klein,
http://www.sanctuminc.com/pdf/whitepaper_httpresponse.pdf
[2] "CRLF Injection" by Ulf Harnhammar (BugTraq posting),
http://www.securityfocus.com/archive/1/271515
|