Working with the Request Validation
page 1 of 1
Published: 22 Sep 2003
Unedited - Community Contributed
Abstract
Explains and demonstrates the functionality and limitations of the Request Validation. This feature was introduced in v1.1 of the .NET Framework.
by Christian Nordbakk
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 39940/ 123

Page 1

During the last couple of months, I have had several encounters with questions and frustrated comments regarding the Request Validation feature that was introduced in v1.1 of the .NET Framework. Many of the questions and, dare I say all, of the frustration seems to come from a common misconception of its functionality and purpose. In this article, I will try to sort out these misunderstandings, and at the end, you will hopefully have a better idea of how you can, and cannot, benefit from it.

This article will assume you have a good understanding of Cross Site Scripting and SQL Injections etc, and that you are aware of the need for validating user-input. If you do not feel too comfortable with the subject, I have provided a set of links to some great articles at the end of this page that will get you up to speed. In addition, since I am not going to discuss the need to handle these things, the article will not sport too many code examples, except some that directly concern the Request Validation.

Why Request Validation?

I hope you all know the answers to that one, and if you don't I suggest you jump down to the end of the article and take a look at the links I have provided.
The dangers of accepting user-input and all data that for some period of time has been out of your control, has been known, and exploited, for a long, long time. Still security breaches related to un-validated data continues to be a huge problem in many applications, both on websites and in business applications. There are probably a hundred reasons, and more, that this still is an issue, but the bottom-line is that it's the sole responsibility of the developer to ensure that such nasty bugs are removed.

Being such a common problem, Microsoft found it necessary to try and force us to deal with it, and this is where the Request Validation comes in to play. Unfortunately it's arrival weren't too clearly announced, and thus many developers first encounter with the feature was that their 1.0 applications crashed and burned when running under the new CLR. As I will show you later in the article, disabling the feature is very easy, so though causing some developers a lot of headaches, it weren't really that big of a problem.

How you benefit from Request Validation.

Contrary to what many developers have thought, Request Validation does not provide you with any kind of validation for free, as the excellent Input Validation web-controls do. In fact, it doesn't provide any functionality at all, and as you will see later on, it will be disabled when releasing the application.

During development, the feature will play an important role though. As long as you take the issues Request Validation is trying to make you deal with seriously, and you don't fall to the temptation and disable it right away, it will help you stay focused on implementing validation of all the input your application has to work with. In some ways I like comparing this feature with a version control system; while being tedious to work with in the beginning, it grows on you, and you will start appreciate what it does for you.

Here is an example of the part Request Validation plays in the development of a simple guestbook entry form. The input will be stored in a database and no HTML or scripts are allowed.

<%@ Page Language="C#" %>
<%@ import Namespace="System.Data.SqlClient" %>
<script runat="server">
    void btnAddEntry_Click(object sender, EventArgs e)
    {
        //Create connection object
        SqlConnection conn = new SqlConnection(
            "data source=MyServer;initial catalog=Guestbook;"
            + "integrated security=SSPI;");

        //Create command object
        SqlCommand cmd = new SqlCommand(
            "INSERT INTO Entries (UserName, Message) "
            + "VALUES('" + txtName.Text + "','"
            + txtMessage.Text + "')", conn);

        //Insert entry into database
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
    }
</script>
<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            Name<br />
            </asp:TextBox id="txtName" runat="server" Width="275px">
        </p>
        <p>
            Message<br />
            </asp:TextBox id="txtMessage" runat="server" Width="274px"
TextMode="MultiLine" Height="143px"> <br /> </asp:Button id="btnAddEntry" onclick="btnAddEntry_Click"
runat="server" Text="Add entry"> </p> </form> </body> </html>

There are several serious problems with this page that could lead to devastating results. First off, there is noting in this example validating that the user is not typing in HTML markup. Secondly, the SQL statement that inserts the entry is built by concatenating text and unvalidated user-input, which could lead to injection of unintended SQL code. To emphasize my point, here's a couple of such devastating inputs which the user could go for.

<script language="javascript">
    document.location("http://www.bigboobs.com");
</script>

or

'; DROP DATABASE Guestbook --

In an application running under the .NET Framework v1.0 this would run like a charm, but afterwards your site would be a pretty mess. You have backups, right?

Running on v1.1 the application would stop execution and raise the HttpRequestValidationException when encountering this, thus no damage would been done. Well, that's not entirely true. Vaildation Exception will only reject unencoded HTML markup and HTML escape codes, it doesn't have any notion of characters or character-combinations that are dangerous to SQL statements, and the last example would actually pass the Request Validation routines. Being aware of this limitation is crucial when developing and testing, so make sure you take note of that.

Knowing the above, making this application secure shouldn't require much of an effort, and are definately worth the work. All that actually needs to be done is making sure all possible HTML are encoded, and wrap the SQL statement in either a StoredProcedure or a parameterized query. After doing so, and testing it thuroghly, it would be safe to disable Request Validation. This can be done in two different ways, but the one most common, and the one that should be used exclusively in the .NET Framework v1.1 builds, is the ValidateRequest attribute of the Page directive.

So, with the above information, we can finish of the example.

<%@ Page Language="C#" ValidateRequest="false" %>
<%@ import Namespace="System.Data.SqlClient" %>
<%@ import Namespace="System.Data " %>
<script runat="server">
    void btnAddEntry_Click(object sender, EventArgs e)
    {
        //Create connection object
        SqlConnection conn = new SqlConnection(
            "data source=MyServer;initial catalog=Guestbook;"
            + "integrated security=SSPI;");

        //Create command object
        SqlCommand cmd = new SqlCommand(
            "INSERT INTO Entries (UserName, Message) "
            + "VALUES(@UserName, @Message)", conn);
        
        //Create and add parameters
        SqlParameter pUserName = new SqlParameter("@UserName", SqlDbType.NVarChar, 20);
        pUserName.Value = Server.HtmlEncode(txtName.Text);
        cmd.Parameters.Add(pUserName);
        
        SqlParameter pMessage = new SqlParameter("@Message", SqlDbType.NVarChar, 1000);
        pMessage.Value = Server.HtmlEncode(txtMessage.Text);
        cmd.Parameters.Add(pMessage);

        //Insert entry into database
        conn.Open();
        cmd.ExecuteNonQuery();
        conn.Close();
    }

</script>
<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            Name<br />
            </asp:TextBox id="txtName" runat="server" Width="275px">
        </p>
        <p>
            Message<br />
            </asp:TextBox id="txtMessage" runat="server" Width="274px"
TextMode="MultiLine" Height="143px"> <br /> </asp:Button id="btnAddEntry" onclick="btnAddEntry_Click"
runat="server" Text="Add entry"> </p> </form> </body> </html>

Note: For better responsiveness in the application and less server-load, you should add validation web-controls to the page to do validation client-side, but not being a topic covered by this article, I chose to keep the example as simple as possible and leave it out.

Configuring Request Validation

As I said earlier, Request Validation can be disabled in two different ways, either through the ValidateRequest attribute of the Page directive

<%@ Page ValidateRequest="false" %>

or by adding the following entry to the Web.Config file in your application directory

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

The difference between these to methods is that the first one will disable validation for the page it is entered in, and the second one will disable it for the entire application. I really can't see any reason why you would ever use the second method, besides as a temporary solution for you 1.0 applications that need to run while you check, correct and doublecheck your code for input bugs.

I can't emphasize enough the importance of using this feature for all it's worth, and not being tempted to disable it before you can guarantee your application can handle all the input anyone can throw at it. The small portion of hassle in the beginning may very well save your job, and you should be thankful it's there!

Conclusion

I have now tried my best to explain and demonstrate the functionality and limitations of the Request Validation, and hopefully, if you've had previous misfortunate encounters with it, you now have a better understanding of how you should work with it and use it. The scope of the Request Validation can actually easily be fittet into one sentence: Request Validation will help you focus on gracefully handling input from your application during development and testing.

Epilog

I hope at least some of you have found this article useful and that I've been able to communicate my knowledge in an informative and easy to understand manner. I always welcome feedback, and being my very first article doesn't make that any less true, so if you have any constructive critisism, comments or ideas, don't hesitate to mail me at cnordbakk@aspalliance.com.

Thank you for staying with me 'till the very end!

Related material

Articles on Cross Site Scripting and SQL-injections



User Comments

Title: abc   
Name: xyz
Date: 6/24/2008 2:36:57 AM
Comment:
That's the behaviour i want to have in my page, but can't find solution
Title: tom31@hotmail.com   
Name: tom
Date: 8/28/2007 4:36:40 AM
Comment:
thx .. nice
Title: lma@yahoo.com   
Name: lma@yahoo.com
Date: 6/20/2006 9:39:37 AM
Comment:
Nice site! David
Title: it's good   
Name: lochg
Date: 1/2/2006 10:08:19 PM
Comment:
I set web.config: validateRequest = "false".
But when I login use FormAuthentication.SetAuthCookies("username",false),it still Validate Input. Anyone help me?

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2014 ASPAlliance.com  |  Page Processed at 11/24/2014 8:21:19 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search