By Jake Edge
October 17, 2008
HTTP response splitting (HRS) is a technique that attackers can use to
inject their own content into a web page. It exploits the way that HTTP
delimits the boundary between its headers and the page content. It also is
an example of that classic web application security bugaboo: improper
filtering of user input.
The basic idea is that by injecting one or more carriage-return line-feed
(CRLF) sequences into the output that a vulnerable web application returns, an
attacker can control what goes to the victim's web browser. The HTTP
response from a web server contains two parts: the headers that describe
the content and the body which contains the HTML for the page.
Each header is delimited by one CRLF and the header section is set off from
the body by two CRLFs. It looks something like:
Date: Fri, 17 Oct 2008 14:31:58 GMT
Server: Apache
Expires: -1
Content-Length: 13355
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
...
Where the first section is the headers, followed by the start of the HTML
content.
The headers above are generated by the LWN web server directly, but
sometimes headers can contain information that comes from a user's
request, often in the form of cookies or redirections. If an attacker can
sneak an extra CRLF or two into a header he controls, he can effectively
create new header lines, or inject his own body content.
Typically this is done by using the URL-encoding values for CR and LF:
%0d and %0a. If the web application is not careful to
check for and filter those characters, the HTTP response can be split. If,
for example, the value of the name variable is set into a cookie
using code like:
Response.Cookies["userName"].Value = request["name"];
then a name like
"
jake%0d%0a%0d%0a<html>surprise!</html>" could
lead to some rather unexpected results. Obviously this is relatively
benign, and only impacts someone who sets their
name that way, but
it does start to give an idea of the power of HRS. Incidentally, the code
above is not random, it is adapted from that used to demonstrate a recent
Mono HRS
vulnerability.
If one can only inject headers into one's own session, it hardly merits
mention, but there are ways for an attacker to inject into a victim's
browser stream. Perhaps the simplest is just by passing a parameter in the
URL in time-honored fashion:
http://some.vulnerable.site/app?name="...". If the attacker can
get the victim to follow that link, they can control headers and body of
what gets returned by the server. Depending on the application, persistent
versions, where a redirection URL, for example, was stored in a database,
might be another way for an attacker to exploit HRS.
HRS is not new, Amit Klein first described
it [PDF] in 2004, but it does keep cropping up. As described in
Klein's paper, it can be used for cross-site scripting (XSS), web cache
poisoning, web site hijacking, and other nefarious activities. More
recently, Jeremiah Grossman found
HRS vulnerabilities to be surprisingly widespread. He was also
surprised at the variety and nastiness of the effects of HRS vulnerabilities.
HRS is not as well known as some of the other web application flaws, but it
is a serious problem that needs to be considered when building or auditing
such applications. Hopefully, we are starting to see some decline in the
number of SQL injection, XSS, and other higher profile vulnerabilities,
which may mean that attackers start looking towards the more obscure for
exploitation. In what is likely to be a never-ending battle for control of
our web applications, getting out ahead of the attacker community can only
be a good thing.
(
Log in to post comments)