In this post, I am going to explain another technique that can be used to bypass the Validate Request filter in an html element context. This technique uses a different character encoding to bypass the blacklist checks that are done.
To recap, ValidateRequest returns false when the following conditions are met:
As you can see, the main goal is to trigger an error when the less than (<) character is passed followed by a specific set of characters. Since it blocks the start character for an HTML element, it makes it difficult to just add new elements to the page. So how do we get around this? Using Unicode-Wide characters, we can pass in a character that looks like the < character, but it really isn't. That character is represented at the value %uff1c. If this value is passed to a varchar field in a SQL database, it will get converted to the real < character. I have not seen this work on a nvarchar field. If this value is than returned to the browser without proper encoding, cross site scripting is possible. Lets take a look at how this works from an example.
- Create an XSS payload for a susceptible field (< script >alert(9)< /script >).
- Change the opening and closing signs to use unicode-wide representation (%uff1cscript%uff1ealert(9);%uff1c/script%uff1e)
- Submit the data to the server.
- The data is stored in a varchar field.
- Retrieve the data without any encoding.
- Cross Site Scripting ensues with an alert box with the value of 9.
This example shows how important output encoding is for remediating cross site scripting vulnerabilities. Input validation important, but not completely bullet proof. The only way to make sure the code is safe is during the output routine.
James Jardine is a principal consultant with Jardine Software. James has over 10 years of experience developing software. His main focus is on Microsoft .Net technologies and secure development. You can read more from James at http://www.jardinesoftware.net.