Another Request Validation Bypass?

Posted by on August 29, 2012

I stumbled across this BugTraq(http://www.securityfocus.com/archive/1/524043) on Security Focus today that indicates another way to bypass ASP.Net’s built in Request Validation feature. It was reported by Zamir Paltiel from Seeker Research Center showing us how using a % symbol in the tag name (ex. <%tag>) makes it possible to bypass Request Validation and apparently some versions of Internet Explorer will actually parse that as a valid tag. Unfortunately, I do not have the specifics of which versions of IE will parse this. My feeble attempts in IE8 and IE9 did not succeed (and yes, I turned off the XSS filter). I did a previous post back in July of 2011 (which you can read here: http://www.jardinesoftware.net/2011/07/17/bypassing-validaterequest/) which discussed using Unicode-wide characters to bypass request validation. 

I am not going to go into all the details of the BugTraq, please read the provided link as Zamir has done a great write up for it.  Instead, I would like to talk about the proper way of dealing with this issue.  Sure, .Net provides some great built in features, Event Validation, Request Validation, ViewStateMac, etc., but they are just helpers to our overall security cause.  If finding out that there is a new way to bypass Request validation opens your application up to Cross-Site Scripting…  YOU ARE DOING THINGS WRONG!!!  Request Validation is so limited in its own nature that, although it is a nice-to-have, it is not going to stop XSS in your site.  We have talked about this time and time again.  Input Validation, Output Encoding.    Say it with me:  Input Validation, Output Encoding.  Lets briefly discuss what we mean here (especially you.. the dev whose website is now vulnerable to XSS because you relied solely on Request Validation).

Input Validation

There are many things we can do with input validation, but lets not get too crazy here.  Here are some common things we need to think about when doing input validation:

  • What TYPE of data are we receiving.  If you expect an Integer, then make sure that the value casts to an Integer.  If you expect a date-time, then make sure it casts to a date time. 
  • How long should the data be.  If you only want to allow 2 characters (state abbreviation?) then only allow 2 characters.
  • Validate the data is in a specific range.  If you have a numeric field, say an age, then validate that it is greater than 0 and less than 150, or whatever your business logic requires.
  • Define a whitelist of characters allowed.  This is big, especially for free-form text.   If you only allow letters and numbers then only allow letters and numbers.  This can be difficult to define depending on your business requirements.  The more you add the better off you will be.

Output Encoding

I know a lot of people will disagree with me on this, but I personally believe that this is where XSS is getting resolved.  Sure, we can do strict input validation on the front end.  But what if data gets in our application some other way, say a rogue DBA or script running directly against the server.   I will not get into all my feelings toward this, but know that I am all for implementing Input Validation.  Now, on to Output Encoding.  The purpose is to let the client or browser be able to distinguish commands from data.  This is done by encoding command characters that the parser understands.  For Example, for HTML the < character gets replaced with &lt;.  This tells the parser to display the less than character rather than interpret it as the start of a tag definition. 

Even with all the input validation in the world, we must be encoding our output to protect against cross site scripting.  It is pretty simple to do, although you do have to know what needs encoding and what does not.  .Net itself makes this somewhat difficult since some controls auto encode data and others do not.

Can We Fix It?

With little hope that this will get resolved within the .Net framework itself, there are ways that we can update Request Validation ourselves, if you are using 4.0 or higher.  Request Validation is Extensible, so it is possible to create your own class to add this check into Request Validation.  I have included a simple PROOF OF CONCEPT!!! of attempting to detect this.  THIS CODE IS NOT PRODUCTION READY and is ONLY FOR DEMONSTRATION PURPOSES..  USE AT YOUR OWN RISK!.  ok enough of that.  Below is code that will crudely look for the presence of the combination of <% in the request parameter.  There are better ways of doing this, I just wanted to show that this can be done.  Keep in mind, that if your application allows the submission of this combination of characters, this would probably not be a good solution.   Alright..  the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Util;

namespace WebTester
{
    public class NewRequestValidation : RequestValidator
    {
        public NewRequestValidation() { }

        protected override bool IsValidRequestString(
            HttpContext context, 
            string value, 
            RequestValidationSource requestValidationSource, 
            string collectionKey, 
            out int validationFailureIndex)
        {
            validationFailureIndex = -1;

            // This check is not meant to be production code...
            // This is just an example of how to set up 
            // a Request Validator override.  
            // Please pick a better way of searching for this.
            if (value.Contains("<%")) // Look for <%...  
            {
                return false;
            }
            else // Let the default Request Validtion take a look.
            {
                return base.IsValidRequestString(
                    context, 
                    value, 
                    requestValidationSource, 
                    collectionKey, 
                    out validationFailureIndex);
            }
        }
    }
}

In order to get a custom request validation override to work in your application, you must tell the application to use it in the web.config.  Below is my sample web.config file updated for this:

  <system.web>
    <httpRuntime requestValidationType="WebTester.NewRequestValidation"/>
  </system.web>

 

Conclusion

We, as developers, must stop relying on built in items and frameworks to protect us against security vulnerabilities.  We must take charge and start practicing secure coding principles so that when a bug like this one is discovered, we can shrug it off and say that we are not worried because we are properly protecting our site. 

Hopefully this will not affect many people, but I can assure you that you will start seeing this being tested during authorized penetration tests and criminals.  The good news, if you are protected, is that it is going to waste a little bit of the attacker’s time by trying this out.  The bad news, and you know who I am talking about, is that your site may now be vulnerable to XSS.  BTW, if you were relying solely on Request Validation to protect your site against XSS, you are probably already vulnerable. 

Comments

Comments are closed.