Inside the new ValidateRequest feature

Note: this entry has moved.

I think that one of the most misunderstood features in ASP.NET 1.1 is the new Request Validation for preventing script attacks. I’m starting to see various posts in the Microsoft public newsgroups asking for help on this, flaming the feature, etc; most of them are just based on a misconception on how this feature works. Moreover, last week I made a presentation (many thanks go to rhoward for sending me his ppt!) introducing ASP.NET 1.1 to a group of about 150 folks at Microsoft Argentina and again I confirmed lots of confusion about this new feature.

 

I’m not going to repeat here what is already written in the docs or in additional articles. Also I believe that looking at this picture will help understand the following text.

 

This new feature is implemented by new methods added to the existing System.Web.HttpRequest type plus a new helper type named System.Web.CrossSiteScriptingValidation.

 

In HttpRequest, the get accesors for properties QueryString, Form and Cookies had been modified to check for dangerous content in the items of the collections they are wrapping before returning them. This new behaviour is only active if ValidateRequest is set to true (either at the Page or application-level; note that true is the default value). If you explicitly set ValidateRequest to false no validation will occur.

 

There are two new methods for validating the previously mentioned collections: ValidateNameValueCollection and ValidateCookieCollection. Why two different methods? Because the types of items to be validated are quite different and may require special handling. Let’s see this in detail:

 

ValidateNameValueCollection validates the items of a NameValueCollection, which is a collection that stores name/value string pairs, i.e.:

 

Name/Key

Value

FirstName

Catalina

CustCode

532

__VIEWSTATE

dDwtMTI3OTMzNDM4NDs7Pn2S7p

 

 

This method will check the Value string for each item but __VIEWSTATE as there is no sense in checking it for dangerous content.

 

ValidateCookiesCollection validates the items of an HttpCookieCollection, which is a collection of HttpCookie objects. The HttpCookie type has quite a bit more information than the simple name/value pair that we previously saw; it has properties like: Expires, Domain, Path, Value, Secure, etc. Like the previous one, this method is only interested in the Value property of the stored items. In this method there is no special handling of items like the __VIEWSTATE case shown above, every item in the collection is checked.

 

Both Validate* methods don’t contain any validation logic coded into them; they just loop through the items in a collection calling the ValidateString method and passing to it each item’s value as an argument. ValidateString still doesn’t implement any validation logic by itself; it uses a new private helper type named System.Web.CrossSiteScriptingValidation (yes, I said private, so forget about extending the validation logic) that has a couple of methods who check for different kind of dangerous content. How this CrossSiteScriptingValidation type looks like? It has four private static methods with very self describing names (IsAtoZ, IsDangerousExpressionString, etc) that perform the actual validation work and it exposes an internal static method named IsDangerousString that is called by the HttpRequest.ValidateString method previously mentioned.

 

The forgotten collections

 

As far as I can tell there seems to be no checking against the Headers and ServerVariables collections. I agree these are not so ‘popular’ as the previous three, but if the attempt was to offer maximum security right out of the box I don’t know why they’ve been excluded. Anyway, it should be great to hear some ‘official’ comments on this J

 

Documentation and cosmetic VS.NET bugs

 

Lastly, there is one new public method HttpRequest.ValidateInput that the docs describe as: “Validates data submitted by a client browser and raises an exception if potentially dangerous data is present”. This phrasing has already caused some confusion on the public newsgroups. Most people expect this method to perform the validation logic and to raise an exception if dangerous data is encountered (well… they’re just expecting what the docs describe). Unfortunately this is not really what this method does which is to just set three flags (one per collection) that will cause validation to happen later when any of the collections are accessed. Because of this, people write code like:

 

[C#]

try

{

     HttpRequest.ValidateInput();
}

catch(HttpRequestValidationException e)

{

     // handle an HttpRequestValidationException
     // that will never be thrown by the code in the try block

}

 

While still at the Bugs Dpt., it seems like VS.NET 2003 has not catch up with this new feature; when a page is selected the Properties window doesn’t shows a ValidateRequest property that would map to the ValidateRequest attribute of the @Page directive (as it actually does with other properties like Trace, Culture, etc.)

 

 

7 Comments

  • Hi Victor


    Thanks for the helpful article on ValidateRequest. I just wanted to know what is the way to work with this feature turned on? I am handling a form with multiple input fields (Consider a basic Personal Profile form.) When do I actually Encode the input strings entered by the user? Or the error will always occur and I cannot handle it in a way if the user enters the "Potentially Dangerous" data.





    If you do not mind, what are your commments on this feature? I see it as erring on the side of the caution.


    Thanks


    Arun

  • Hi Arun,





    Thanks for your comments.





    Actually when this feature is turned on you dont have much of a chance to change the way it works (ie.enconding before it gets "checked", extending the validation rules, etc). You should encode the content at the client-side using some javascript, before the data gets submitted.





    If you disable this feature you should rely on Server.HtmlEncode and Server.HtmlDecode for handling input.





    Overall, I think this feature and the fact that is enabled by default is a good thing. Why? If your site stops working because of it, it makes you learn about it and learn the security implications of turning it off without having your own validation. It really helps in making sure you get noticed about this, and the fact that your site may be exposed to one of the most common type of attack.








  • Where can the following code be added in the Page lifecycle? It seems like I can't put it in the page load...





    try

    {

    HttpContext.Current.Request.ValidateInput();

    }

    catch( System.Web.HttpRequestValidationException xxx )

    ...





    Thanks.

  • I manage Data Islands at client side (in ASP.Net applications) and then posted them to the server. With Net FWK 1.1 I receive an Exception because of ValidateRequest.

    I can disable it, but is there a better solution?



    Thanks



  • <HTML>

    <HEAD>

    <SCRIPT Language=JavaScript>

    window.open("default.aspx","_parent", "toolbar=0, menubar=0, resizable=no, status=no");

    </SCRIPT>

    </HEAD>

    </HTML>

  • Is there a way to programitically disable the page validation at run time?

  • <script> test



    nice article

Comments have been disabled for this content.