Friday, August 23, 2013

Cross Site Scripting vs. ASP.Net EnableValidation="true"

A friend of mine recently told me about a debate he was participating in with a colleague of his. His colleague stated that the reason ASP.Net applications are so secure, is because when EnableEventValidation flag on a page is set to true it will catch any Cross Site Scripting (XSS) attempt and throw an error.

I'm here to say... his Colleague is absolutely correct!

Wait... that's not right. They are actually mistaken. And unfortunately I've met a number of individuals who carry this same belief erroneously.

This is a perfect example of the "Defender's Dilemma." Where-in a defensive posture must account for 100% of all attacks and vectors, which may be costly to the point of exhaustion, or accepting attacks as inevitable because the attacker need only be right one in a million attacks to perform a breach.

This said, yes, EnableEventValidation may present a thorn in an attacker's side. Particularly when all of the sweet sweet pwnage is so rife with opportunity because of that one field that is so obviously vulnerable. But then when you drop your <script> it's thwarted immediately and you immediately wish it was a PHP host you were attacking instead.

But reality is contrary to the surprisingly common misconception that the this flag prevents XSS attempts in all cases. It just doesn't. And there are good reasons why it doesn't. XSS has a huge key-space for potential vectors, arguably an insurmountable key-space. This is compounded by the fact that new methods can be evolved from previously benign unexpected vectors. A perfect example of this would by UTF-7 encoding attacks. A bug that affects only few browsers nowadays. Like I said the defender has to always be right and the attacker only has to be right once. Another issue is that some XSS is represented in manners which may easily represent real valid data. e.g. they may not contain tags at all.

Consider the following as a simple example.

The ASP.Net Page definition, simple example:
<%@Page ... EnableEventValidation="true" %>
<div style="<%= Request.QueryString["style"] %>">Welcome Home Marty</div>

Though this is obvious to any conscientious developer, this sort of code can slide into a code base if it is written by a less experienced coder and approved too hastily by an experienced coder. How the code gets into a code base is largely unimportant, what is important is assume you've got something like this, and maybe it's a good time to do a code review if you're relying entirely on the EnableEventValidation flag to protect you.

When exploiting this, and this is one of my favorite methods personally, try leveraging javascript events. For instance, use the onmouseover event to fire your arbitrary javascript when the affected user mouses over a particular object:


No tags, but the server will process the request and render the onmouseover event with the javascript payload. An important note when testing this is, you know it's worked because it passes by the EnableEventValidation - no exception thrown. However, if you attempt to exploit this against users of I.E. or Chrome you'll likely see little to no success (error towards no success). This is because these clients recognize that script that is executing was passed to the server by the client. This is not a feature of ASP.Net but instead of the client itself.  So if you use Firefox without NoScript installed, it should be responsive to this attack.

Now in a similar situation where a client might get to set their choice of style by inserting into a database, this is a different story. This is the more troublesome persistent XSS attack and the vulnerable code may take the likeness of something such as:

<%@Page ... EnableEventValidation="true" %>
<div style="<%= myDataBaseObject.ChosenStyle %>">Welcome Home Marty</div>

In which case even I.E. and Chrome will not have a frame of reference for the XSS. The will not be able to distinguish the XSS from an attack or valid data and will render the page with the onmouseover event ready and willing to fire!

The solution to this is, encode your outputs in a context sensitive manner when dumping information to your clients. By all means EnableEventValidation, but do not rely on it as a replacement for secure programming practices!

And it should be noted, this flag does not provide any protection for other vectors like SQLi, CSRF, LFI, CR/LF, etc. It is really designed for anti-XSS.

So until next time... Hack legal, Hack safe, but most of all... Hack Fun!