Here I’ll demonstrate how it’s possible to evade ASP .NET Request Validation and take advantage of Internet Explorer 9 quirks to execute a working XSS exploit. Let’s look at a scenario…
You suspect an ASP.NET application you’re testing is vulnerable to reflected XSS because it displays user input to the screen. Its login page includes a registration function and if a user inputs the wrong registration number (passed via a GET parameter in this instance), the application displays an error message and reflects the entered registration number to the screen as follows:
You know from your testing that the application performs no output encoding. Initial attempts to exploit this vulnerability using a couple of basic test strings passed in the GET parameter of the URL:
http://192.168.34.5/testweb/index.php?registration=<script>alert(‘XSS’)</script>
and
http://192.168.34.5/testweb/index.php?registration=<%00script>alert(‘XSS’)<%00/script>
Both tests generate the following error:
This response indicates the application is relying on ASP.NET Request Validation. From a security perspective, this is not sufficient, as we will see in a moment. In fact, Microsoft lists enabling Request Validation as step 1 in a 5 step process and specifically states: “Do not rely on ASP.NET request validation. Treat it as an extra precautionary measure in addition to your own input validation.”[1]
Request validation will detect inputs such as <[a-z], <!, </, <? but one shortfall is its tolerance of the % character. Therefore, <%script>alert(‘XSS’)<%/script>
will pass the validation filter undetected. That by itself does not get us a successful XSS exploit because no browser that I’ve seen will execute the script…but it does get us one step closer.
As recently reported by Zamir Paltiel in August of this year [2] this Request Validation bypass method, coupled with the fact that Internet Explorer is very forgiving when it comes to rendering an HTML tag starting with <% could allow an attacker to use the style attribute and expression function in an HTML tag to execute a script as follows:
<%tag style=”xss:expression(alert(‘XSS’))”>
I’ve successfully tested this in Internet Explorer 9 with some caveats. First (and most obviously) the XSS filter must be disabled. If not, your expression will be automatically modified and you’ll receive an error message similar to this …
With the XSS filter disabled, you’re ready to test using an input such as
http://192.168.34.5/testweb/index.php?registration=<%tag style=”xss:expression(alert(‘XSS’))”>
which results in the following response:
Now we’ve successfully bypassed the ASP.NET Request Validation and the browser seems to be treating the test input like valid HTML since it’s not being rendered as text. Closer inspection of the HTML source confirms.
So why isn’t the script being executed? In my testing, the <!DOCTYPE> declaration foils such an attempt to automatically execute the script. I’ve tested with a simple <!DOCTYPE> string as well as with the common valid DOCTYPE declarations (HTML 5, 4.01 Strict, Transitional, Frameset, etc), all with the same results—failure to execute the script. Why? By design, the DOCTYPE tells your browser how to parse the HTML and CSS as well as how to execute scripts. The specific declaration (or lack thereof) will determine the mode used by the browser (standards, almost standards or quirks). You can easily test this yourself by creating a new HTML file with the following:
<!DOCTYPE HTML>
<html>
<body>
With DOCTYPE
<%tag style="xss:expression(alert(‘XSS’))">
</body>
</html>
Opening the page in IE 9 should simply print “With DOCTYPE” and not execute any script. Now try the same thing without a DOCTYPE declaration:
<html>
<body>
Without DOCTYPE
<%tag style="xss:expression(alert(‘XSS’))">
</body>
</html>
You should get the following response (if prompted, allow the script to execute):
Unfortunately, chances are most production sites will be standards compliant and therefore have a DOCTYPE declaration. That being said, all is not lost in our quest to demonstrate this vulnerability on such a site…we just need a little help from the user.
While DOCTYPE does seem to impede automatic execution of script in a malformed HTML tag using the standard style attribute, we can turn our attention to the event attributes, such as onmouseover, onmousemove, etc. Use of an event attribute will no longer rely on automatic execution of the script upon page load and will only require minimal interaction on the part of the end-user. Let’s test and see:
http://192.168.34.5/testweb/index.php?registration=<%tag onmouseover="(alert('XSS'))"> is invalid. <%br /> Click here to see why. Once you understand why it
Success! The test string used in this example included the onmouseover event attribute as well as some custom text to modify the output message and entice the user to execute the script. While admittedly this rudimentary message might not fool everyone, just the swipe of the mouse pointer over the text area will execute the embedded script.
What steps do developers and users need to take to prevent this situation?
For developers, relying solely on a web application framework’s built-in input validation mechanisms (such as ASP .NET’s Request Validation) is never sufficient as Microsoft clearly states:
It is strongly recommended that your application explicitly check all inputs it uses in addition to the request validation performed by ASP.NET. The request validation feature cannot catch all attacks, especially those crafted specifically against your application logic.[3]
Developers must employ additional validation checks specific to the input being processed by the application, using whitelist approaches when possible. For example, if the application accepts a registration code as an input (similar to our mock example) and that code is always alphanumeric, there is no reason to ever accept special characters such as <, regardless of what characters follow. Failure to implement proper server-side validation puts the protection burden on the client browser, which as we’ve seen is not reliable. Also, output encoding is a must to ensure any characters that do make it past input validation are rendered harmlessly in the browser. Finally, proper error handling will prevent the display of robust error messages that give clues as to what type of validation is being performed server-side.
While the onus of preventing these attacks falls primarily on the application developers, users should always enable sufficient browser protections. In this example, enabling the XSS filter would have prevented this attack, despite the shortcomings of the application as illustrated by the following screenshot.
I have not been able to get this XSS attack vector to work in IE 8 or Firefox (which is not as forgiving in rendering malformed html).
[1] http://msdn.microsoft.com/en-us/library/ff649310.aspx#paght000004_step1 [2] http://www.quotium.com/prod/ResearchCenter/XSS-NetrequestValidation.php [3] http://msdn.microsoft.com/en-us/library/system.web.httprequestvalidationexception.aspx