Web Pages Beta 2–Request Validation

Today we released all kinds of goodness at Microsoft for ASP.NET developers:

  • - Web Pages Beta 2 – An update to our new support for adding simple Razor syntax pages to to web applications.
  • - MVC 3 Beta – An update to our preview release from a few months ago with several enhancements around razor, helpers, unobtrusive javascript, dependency injection and more.
  • - NuPack – Package manager for finding, adding, upgrading libraries for your .NET projects. This makes it super easy to find libraries for writing your applications and easily installing them into your projects including their dependencies.

I want to focus on Web Pages today which I’ve not written about since we released the first release but I’ve been involved in from the beginning. If you don’t have any background on Web Pages this is a very simple way to do web development drawling parallels to programming in classic ASP or PHP. It does not require development tools like Visual Studio, or a build system to build projects. You can just take an empty folder and and drop in a .cshtml (C#)or .vbhtml (Visual Basic) file into the folder that contains a combination of markup and razor syntax and point your browser and you are off and running.

For someone like myself Web Pages reminds me of when I first started web programming years ago with classic ASP. I could take my HTML files and add a little bit of inline code to get dynamic web pages. It was a great way to learn web programming and Web Pages brings this same simplicity to ASP.NET. All of the concepts you learn while programming in Web Pages you should be able to use if you decide to move up to our more complicated frameworks like MVC.

To learn more about Web Pages check out our online manual: https://www.asp.net/webmatrix/tutorials/1-getting-started-with-webmatrix-and-asp-net-web-pages.

Today I’m going to talk about Request Validation which is a security feature that is built in ASP.NET. Request Validation is a security measure that is built into ASP.NET. The purpose of this feature is prevent script or HTML injection attack in websites. Such attacks happen when a webpage has some input fields on the page that accept input. If a person fills these input fields with script or html and the web page outputs the content back the user the web browser will run the script or html potentially causing the browser to do something bad.

To prevent this ASP.NET looks at any input that it sees and if it looks like unencoded html and error will happen and the request will not be processed. Lets take a simple application and see what this looks like:

 <!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <form method="post" action="">
            <label for="description">Description:</label>
            <textarea name="description">
            </textarea>
            <br />
            <input type="submit" value="Submit"></input>
        </form>
        <br />
        @if (IsPost) {
            <div>
                Your description is: @Request["description"]
            </div>
        }
    </body>
</html>

 

If I type something in the field on the page that looks like html:

 

image

And the press the submit button I will get an error instead of having my page run properly:

image

This shows an example of ASP.NET working to be secure by default and making the developer make the decision if they want allow such input. You might be asking yourself why would you want to allow someone to type html into a field. The best example is when you build a web page that contains a rich html editor, today you see these in all kinds of applications on the internet such as blogs. I’ve added the TinyMCE editor to my application because I want to have a rich editor. I downloaded the scripts from the TinyMCE site and added them to the scripts folder in my project. Next I added the following markup above my form:

 <script type="text/javascript" src="scripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
    tinyMCE.init({
        mode : "textareas",
        theme : "simple"
    });
</script>        

 

This enables the rich html editor on my page and running the page in the browser now looks like this:

image

Now any in the description field will fail with the same server error we saw above when pressing the submit button. This is because the fancy effects of being able to bold, strike through and underline you see in the example above happen because the field contains html. I need someway of turning off the validation for just this one field. Older versions of ASP.NET have had ways of turning this off:

ASP.NET 1.1 – ASP.NET 3.5 SP1:

In Web Forms you can add the following page directive: <%@ Page validateRequest="false" %>

In MVC you would place the following attribute on the action method for your controller: [ValidateInput(false)]

But these are not a good solution because they turn off Request Validation for the entire page! If I had other fields on the page for example a <input type=”text” name=”name”/> field in which I do not want to allow html or script input it is no longer protected because I’ve turned off request validation for the whole page. Now I need to manually validate the input for each field to make sure the input is safe.

ASP.NET 4:

We made Request Validation even stronger by making it happen earlier in the request pipeline. This meant that even low level ASP.NET components called Handlers and Modules could be protected. But because we are validating input so early you can no longer turn it on or off at the page level. If you had pages that needed to support html input you had to disable the .NET 4 mode and re-enable the .NET 1.1/2.0 mode using settings in the web.config file.

The Future: Web Pages, MVC 3 and in the next framework Web Forms:

Clearly we needed a much better solution. I should be able to turn off the request validation just for the fields that need to support html type input. While building Web Pages we were able to keep both the additional security we enabled in .NET 4 and support this using the new Validation.Exclude method. Here is how I add support for this by adding it to the top of my page:

 @{
    Validation.Exclude("description");
}

You can pass multiple fields or if you want to disable Request Validation for the entire page you can call Validation.ExcludeAll. Now if I run the page in the browser you will see this:

 

image

You might be asking yourself why does the text in the rich html editor look one way and when I display in the page does it look different? We have just run into another security feature that ASP.NET razor syntax has, whenever we output values we automatically encode them:

 Your description is: @Request["description"]

The value of @Request[“description”] is automatically html encoded. This again is an example of security being on by default so if values containing html or script are output the browser will not execute the html/script. If the developer knows that the data they are outputing is valid they can create a special type called an HtmlString and return the value of that which will not be automatically encoded. Here is  the changed code in my sample:

 

 @if (IsPost) {
    var desc = new HtmlString(Request["description"]);
    <div>
        Your description is: @desc
    </div>
}

Now I’m grabbing the value of the Request and creating a new HtmlString with that value. HtmlString is a special type that ASP.NET does not encode when it is output. Now running my page I will get the output I expect:

 

image

In this blog post I’ve covered a lot of topics but to recap:

  • - Web Pages validates input by default for security
  • - Web pages allows this validation to be disabled on a field by field basis
  • - Web pages encodes output by default for security
  • - Web pages allows output to be put into an HtmlString which allows it to be output with encoding

I hope to post about more Web Pages features soon…

Comments

  • Anonymous
    March 24, 2014
    What you had to download "the scripts from the TinyMCE site and added them to the scripts folder in my project." to make this work in webmatrix, any help would be appreciated. Thanks in advance. Srini sirini23@yahoo.com