Event validation of controls in ASP.NET 2.0

This is the second part in a post on EventValidation in ASP.NET 2.0. In this post I will address the topic of event validation. This new feature becomes apparent when trying to use client callbacks in combination with new values for controls. If you are unfamiliar with the topic of client callbacks and the resulting exceptions that may occur, read the first part here.


The question to answer: why and what is the new feature in ASP.NET 2.0 for event validation? I’ll work towards the answer in steps.


Have you ever tried to manipulate the items in a dropdownlist, say by changing values and maybe adding additional items? I know I have, in a study of SQL injection attacks on ASP.NET web applications. As it turned out the values of the dropdownlist come from the viewstate instead of from the page. And the extra items in the dropdownlist are discarded because they do not appear in the viewstate. A very good thing indeed.


With client callbacks it is very likely that you will be adding new items/values to controls (which might be empty initially). You use the Document Object Model of the browser and manipulate the controls with this DOM through JavaScript. In this scenario the ASP.NET runtime should not discard the new values. We would have a pretty unworkable situation otherwise. Remember, we want to offer a better user experience by putting the values in without a server roundtrip postback. The new values are a risk from a security viewpoint. So the ASP.NET runtime protects itself by requiring you to register the values that will be posted as part of an event. It will throw exceptions for any values that were not registered before the postback. In the previous post, the new values weren’t registered. Hence the exception.


So, now you know were the exception originates from. Next question is: how do I play by the rules?
There is a way to disable the event validation mechanism. Just add the EnableEventValidation=”false” attribute to the page or control directive. Or, you can go for the <pages enableEventValidation=”false”> approach, to apply it to all pages at once. BUT, both methods will disable all validation of values of controls in the entire/all page(s) and opens up the security holes that were meant to be covered. In other words: you will need to validate your postback data yourself! It is similar to turning off ValidateRequest for the page and having to check for tags in the received input. Remember one of the main security rules: NEVER EVER trust user input. You should be on the safe side with that.


I hear you say: “So what’s with this RegisterForEventValidation method?” Well, normally, a control will register each of the values that it knows will be postable from the page. You do so at the time of rendering of the page. Here’s a fragment:


protected override void Render(HtmlTextWriter writer)
{
  ClientScript.RegisterForEventValidation(this
.ListBox1.UniqueID, “One”);
  base
.Render(writer);
}


With this code in place you would be allowed to do a postback with the value “One” from ListBox1. There is a big downside to this approach when trying to use it in combination with client callbacks. Since the page only gets rendered once, you need to output ALL possible values at that time. This might not be feasible in a lot of situations, if any. This means you are kind of stuck with setting EnableEventValidation to false.


This will make the story complete: every control in ASP.NET 2.0 has to register all the events and arguments (if applicable) during the render phase. E.g., a button would typically call RegisterForEventValidation passing in itself as the control. No arguments necessary. Also, the control must be decorated with the SupportsEventValidationAttribute. During postback (to be precise: at RaisePostBackEvent) a control will call the ValidateEvent method and pass in the event argument it has received. This will check the administration of registered events and arguments to see if the postback data is allowed. If not, the terrible exception is thrown again.

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s