Tuesday, September 3, 2013

Bypassing XSS Mitigations with HTTP Parameter Pollution

By Piyush Mittal.

HTTP Parameter Pollution is overriding or adding HTTP GET/POST parameters by injecting query string delimeters. Basically, the attacker sends the same parameter multiple times to affect the application. This can also be exploited by specifying a new random parameter and adding it to the request. The server may combine the values of the duplicate parameter or reject one of the two values. The following table summarizes the known behaviors in different web servers:

from Luca Carettoni's and Stefano di Paolo's presentation at OWASP EU09

Vulnerable Request

I was recently looking at an application that appeared to be vulnerabile to cross-site scripting since it was possible to inject <, >, ",;, etc.... , but something (web application firewall/blacklisting) would strip HTML tags and attributes. From here on out, we'll refer to anything that might be doing filtering as "mitigations". The vulnerability was in the "category" parameter sent within a POST request to "search.htm":

POST /search.htm HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 109


Whenever any sort of HTML tag would be provided to the category parameter, the application would redirect the user to a error page that referenced OWASP:

HTTP/1.1 302 Moved Temporarily
Date: Tue, 03 Sep 2013 02:12:58 GMT
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.4; JBoss-4.3.0.GA/Tomcat-5.5
Content-Length: 0
Location: https://www.somesite.com/error.html?code=OWASP
Connection: keep-alive
Content-Type: text/html; charset=UTF-8


It's suprising how many mitigations can be bypassed right out of the box by simply changing the request from a POST to a GET (or vice versa). Unfortunately, for this exercise, changing the request did not work. However, the application supported it, which made exploitation easier.

Traditional Bypass

First I tried to the standard filter evasion techniques by trying different parameters, etc.. Here's a list that were all blocked:

  • "onclick
  • "ondblclick
  • "onmousedown
  • "onmousemove
  • "onmouseover
  • "onmouseout
  • "onmouseup
  • "onkeydown
  • "onkeypress
  • "onkeyup
  • "onabort
  • "onerror
  • "onload
  • "onresize
  • "onscroll
  • "onunload
  • "onsubmit
  • "onblur
  • "onchange
  • "onfocus
  • "onreset
  • "onselect
  • “><ScRiPt>
  • “><SCRIPT>
  • “><script//
  • “><script/**/
  • “><script+
  • “><script%20
  • “><script
  • “><%73%63%72%69%70%74>
  • “><<script>>
  • “><s/**/c/**/r/**/i/**/p/**/t>
  • “><s//c//r//i//p//t>
  • “><s+c+r+i+p+t>
  • “><s%20c%20r%20i%20p%20t>
  • “><%26%23x73%26%23x63%26%23x72%26%23x69%26%23x70%26%23x74>
  • <object
  • <div
  • <img
  • <a

HPP as a Bypass

As you may have guessed, by simply specifying the category parameter twice, it was possible to completely bypass the mitigation. The second instance of the parameter was ignored by the mitigation, then at the server both parameters were combined, allowing the script injection!

Here's the final URL:


No comments:

Post a Comment