Me Myself & C#

Manoj Garg’s Tech Bytes – What I learned Today

Posts Tagged ‘A potentially dangerous Request.Form value was detected from the client’

Request.ValidateInput() : A common misconception

Posted by Manoj Garg on September 7, 2009

Attackers try to exploit smallest possible hole into the security of a website. A common and widely used method is script injection attack or cross site scripting where attacker tries to put some script as input to the website and tries to damage the system. A simplest example could be passing a java script function that redirects every request to a page to some other site next time onwards or passing a SQL DML statement which deletes/updates record into the database.

ASP.Net provide some measure to mitigate this risk of script injection. One of such technique is validating each and every input entered by the user before passing it on the server automatically. In this approach IIS parses the input before it is sent to the worker process and checks it for potential dangerous characters lie <, > etc. If any of such character is found in the input request, an exception is thrown, thus saving the site from a possible attack.

The exception thrown is

“A potentially dangerous Request.Form value was detected from the client”

In ASP.NET this feature can be applied per page basis or for the entire site depending on the requirement. To enable input request validation for the entire site, set validateRequest attribute of page section in web.config to true.

<configuration>
    <system.web>
        <pages validateRequest="false" />
    </system.web>
</configuration>

Similarly, to override the request validation or enable/disable request validation on a page ValidateRequest attribute of Page directive can be set to true/false respectively. Setting this attribute to true instructs the IIS to check the sanity of the incoming request before passing it on.

So this approach won’t let any script to pass through. But there are situations where you need to take a script or the prohibited characters like <,> as input from user, at the same time preventing a misuse of this opportunity of script injection.

A commonly used approach in ASP.NET for this scenario is:

  1. Set ValidateRequest to false for that page.
  2. Encode the input entered by the end user using Server.HtmlEncode(): Encoding ensures that all the stop words(potentially harmful characters) are converted to an equivalent HTML character encoding e.g. “<” is converted to “&lt;” etc.

I had a similar requirement, few days back, when in our application on “contact us” page, We wanted to allow user to enter html scripts into a text box. So we disabled the ValidateRequest attribute to false and used Server.HtmlEncode() method to encode the entered input. But at the same time we didn’t wanted the user to pass something malicious through the query string or the cookies. ASP.NET also provides a method on the Request object named ValidateInput(), which validates the request input passed by the client to the server. And if something fishy is found in the request an HttpRequestValidationException exception is thrown. And this is where the confusion gets in.

As per MSDN, Request.ValidateInput() method ….

The HttpRequest class uses input validation flags to track whether to perform validation on the request collections accessed through the Cookies, Form, and QueryString properties. The ValidateInput method sets these flags so that when the get accessors for the Cookies, Form, or QueryString property are invoked, input validation is performed. Validation works by checking all input data against a hard-coded list of potentially dangerous data.

If the validation feature is enabled by page directive or configuration, this method is called during the page’s ProcessRequest processing phase. The ValidateInput method can be called by your code if the validation feature is not enabled.

As this definition says that ValidateInput method does nothing but sets some flags indicating that all access to user input must be validated before using it. But normally developer tend to call Request.ValidateInput() method and then expect it to throw the HttpRequestValidationException exception, which will not happen since this method doesn’t throw any exception, rather any access now onwards to input will throw the above mentioned exception.

Lets disassemble the Request.ValidateInput method.

public void ValidateInput()
{
    this._flags.Set(1);
    this._flags.Set(2);
    this._flags.Set(4);
    this._flags.Set(0x40);
    this._flags.Set(0x80);
}

As shown in the above code snippet, this method has just some set methods calls. Actually these method set a flag for one of the input approach that can be used by the client. Like querystring, form input , cookie etc.

So what does this setter method do?? This method is merely an indicator for the getters methods of each of the request fields to check the sanitation of the value before returning the value to the requestor and if there is some invalid input then throw the HttpRequestValidationException.

So to check for invalid input in Form values, we need to access form values collection of the request as Request.Form after the call to Request.ValidateInput(). Following is a sample code for validating Form values,

String firstName = string.Empty;
try
{
    Request.ValidateInput();
    //Access the Form value collection. So if there is any non complient input entered by user.. It will throw an exception
    System.Collections.Specialized.NameValueCollection nvc = Request.Form;

    firstName = txtName.Text.Trim();
}
catch(HttpRequestValidationException)
{
    firstName = HttpUtility.HtmlEncode(txtName.Text.Trim());
}

here line in yellow color will throw an exception if at all there is some bad data in the input. Then in catch we can use HtmlEncode() to encode the user input.

Similar approach can be used while accessing cookies or QueryString.

Posted in .Net 2.0, ASP.Net, C# | Tagged: , , , | 3 Comments »