By default, the ASP.NET MVC framework prevents you from submitting form data that contains potentially malicious content. This feature is called request validation.

For example, submitting the following text in an HTML input field causes the ASP.NET MVC framework to throw an exception (Figure 1):

<script>Alert(‘I am evil!’);</script>

Figure 1 – An evil form post

clip_image002

This is a good feature. You don't want people sneaking scripts into your website that can steal passwords or other sensitive user information. Normally, you want to leave request validation enabled.

There are situations, however, when it is perfectly legitimate to want people to submit text that contains HTML markup to a website. For example, you might be hosting a discussion forum on ASP.NET MVC and you want to enable people to submit messages that contain HTML tags.

Unlike a Web Forms application, you cannot disable request validation by using the <%@ Page ValidateRequest=”false” %> directive. You also cannot disable request validation in the web configuration (web.config) file. If you want to disable request validation then you must use the [ValidateInput] attribute.

You apply the [ValidateInput] attribute to the controller action that accepts the form input. For example, the Create() action below has request validation disabled:

[C#]

//
// POST: /Home/Create
 
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude="Id")]Product productToCreate)
{
    if (!ModelState.IsValid)
        return View();

    try
    {
        _dataModel.AddToProductSet(productToCreate);
        _dataModel.SaveChanges();

        return RedirectToAction("Index");
    }
    catch
    {
        return View();
    }
}

[VB]

'
' POST: /Home/Create
<ValidateInput(false)> _
<AcceptVerbs(HttpVerbs.Post)> _
Function Create(<Bind(Exclude:="Id")> ByVal productToCreate As Product) As ActionResult

    If Not ModelState.IsValid Then
        Return View()
    End If

    Try
        _dataModel.AddToProductSet(productToCreate)
        _dataModel.SaveChanges()

        Return RedirectToAction("Index")
    Catch
        Return View()
    End Try
End Function

If you decide to disable request validation, make sure that you HTML encode any text submitted by a user that you display in a view. Always use the <%= Html.Encode() %> helper method when displaying content.

If you liked this blog post then please Subscribe to this blog.
posted on Friday, February 20, 2009 3:40 PM | Filed Under [ ASP.NET ASP.NET MVC Tips ]

Comments

Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Marwan
on 2/21/2009 4:19 AM

nice tip
thanks
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Max Fraser
on 2/21/2009 4:28 AM

thanks - I wish there where a .ToHtmlEncode() like there is a .ToString()
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by ToddLF
on 2/21/2009 4:45 AM

"thanks - I wish there where a .ToHtmlEncode() like there is a .ToString() "

Sounds like a pretty easy extension method to me
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Shawn
on 2/21/2009 5:40 AM

Actually, using Html.Encode() on the output defeats the purpose of allowing HTML markup on the input in the first place.
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Joe Chung
on 2/21/2009 10:53 AM

Allowing HTML markup as input is a bad idea.
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Stephen.Walther
on 2/21/2009 1:04 PM

@Shawn -- You might want to display content that contains < and > characters. For example, typing <img> in this commment displays instead of the tag.
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Shawn
on 2/22/2009 7:33 AM

@Stephen - yes, encoding if you want to display the angle brackets makes sense, but generally you want to display the picture not the text , which encoding prevents. Your blog software must allow the tag through in order for it to be rendered as an image. My point is that often the reason you're allowing html input is so that it displays as matching html on the output as well.

@Joe - allowing some form of markup is required if you want users to do more than boring plain text. Take Stephen's blog here for example - it would be nearly unreadable if he couldn't provide rich markup with images, headings, the slick source code listings, etc.
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by jack
on 2/22/2009 10:23 PM

this is really good
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Mario
on 4/3/2009 6:14 AM

For those special situations html encoding ", could cover 90% of problems
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Mario
on 4/3/2009 6:19 AM

I meant html encoding "<.S. Cr.ipt >" and "<./ Scr.ip t>" dooh
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Joshua Beall
on 6/18/2009 8:20 AM

So, there's no way to globally disable input validation? This is annoying. Consider a CMS application that has countless actions where user input is (and should be) HTML. Does every action need to be decorated with the [ValidateInput(false)] attribute?

I realize the desire for security, but the truth is, programmers need to take responsibility for their own code. The framework can't always take care of everything for you, and in this case, the adults among us would like to just be able to globally disable this and do our own input validation.
Gravatar
# re: ASP.NET MVC Tip #48 – Disable Request Validation
Posted by Stephen.Walther
on 6/19/2009 8:21 AM

@Joshua Beall -- Good question. You don't need to place the attribute on every controller action. You can place the attribute on the controller class itself. Another alternative is to create a base controller class and place the attribute on this base class. That way, request validaton would be disabled for every derived controller automatically.
Comments have been closed on this topic.