Previously, some hacks have been reported to successfully bypass anti-XSS filters:
I am not sure which is status of these. Those may or may not be fixed in browsers. However, let’s look another method.
Header injection and response splitting
The key point in this method is that we do not use a usual XSS vulnerability, but HTTP Header injection / HTTP Response Splitting [OWASP]. It is a vulnerability, where user input is placed on HTTP response header without proper validation.
A typical example is open redirect flaw. A vulnerable page allows redirection according to user input without proper validation. Request could be something like this:
While the response would be something like this:
HTTP/1.1 302 Found Date: Thu, 26 Jun 2014 22:41:46 GMT Location: http://www.example.com/foobar Content-Length: 0
By adding new lines to “url” -parameter, the attacker could inject arbitrary HTTP headers to the response:
Which would produce the following HTTP-response:
HTTP/1.1 302 Found Date: Thu, 26 Jun 2014 22:41:46 GMT Location: X-Random-Header: foo Content-Length: 0
Naturally, the attacker could also specify Content-Length -header and set arbitrary response body, which would exploit a reflected XSS vulnerability. Luckily we have these anti-XSS filters in most modern browsers, which would prevent this. Wait, would they?
Since we can inject arbitrary headers to the response, we can also add the following header:
This header in HTTP response disables the anti-XSS filters that are built into most browser. The whole request could be for example (by splitting the response):
In this case, the response would be something like this:
HTTP/1.1 302 Found Date: Thu, 26 Jun 2014 22:41:46 GMT Location: HTTP /1.1 200 OK X-XSS-Protection: 0 Content-Length: 37 <script>alert('xss')</script>
Now, the browser ignores initial “HTTP/1.1 302 Found” response and considers the latest “HTTP /1.1” the valid response. Now the browser anti-XSS filter is disabled, so that the reflected XSS is executed.
I tested a simple example of this attack both on Google Chrome 34.0 and Safari 7.0.4, and it worked nicely.
It seems that whereas the anti-XSS filters detect and prevent typical reflected XSS attacks, they completely ignore header injection attacks. This allows an attacker to use reflected cross-site scripting on web pages vulnerable to header injection / response splitting.