How to use ValidateInput action filter in ASP.NET MVC?
Action filters are very powerful as it allows you to intercept the action’s requesting, requested and result’s executing, executed methods to perform some custom processing that your application needs. This can be very useful if you don’t want to rewrite some piece of code for every action or controller and that’s a good way to roll your own action filter. In this post I’ll you how to use ValidateInput action filter in ASP.NET MVC framework.
What is the need of an action filter?
If you would like to apply any pre or post processing logic to a controller action and it’s result, ASP.NET MVC framework provides what is called as action filters that can be used in your application. An action filter can be consumed at different levels like at controller or action or global level. If a filter is applied to just an action, it’s only available to that action. If it is applied at controller level, it works for all the actions inside that controller. And self-explanatory, if it is defined at the global level, i.e. using FilterConfig in Global.asax.cs file, then it applies to all of the controllers and thus, actions.
To learn more about action filters, make sure you read my detailed post about it where I list all the action filters available out of the box in the framework and also how to roll your own action filter.
Why even bother validating actions?
It is very easy for someone to post or send any harmful data to your application such as scripts like SQL, JavaScript, HTML, etc. This data may arrive in any form, for example, route data, query string or form collection. Therefore, it is very important to validate all the inputs at the right entry point to avoid such attacks like Cross-site scripting (XSS). If a user write some scripts or HTML in a text-box and try to send it to the server, by default, application will tackle this request as a possible threat and will show an error message that says: “A potentially dangerous Request.Form value was detected from the client (Description='<h2>This is html tag..</h2>’)”. It also gives a long description of the issue that why the framework thinks this can be a possible issue.
How can ASP.NET MVC help us?
To tackle the issue discussed above, the framework provides a `ValidateInputAttribute` out of the box that represents an attribute that is used to mark action methods whose inputs must be validated. This is found in System.Web.Mvc namespace. The syntax of this attribute is shown below:
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class ValidateInputAttribute : FilterAttribute, IAuthorizationFilter
As per the syntax, this attribute can be used either on a controller (Class) or action (Method). If this is applied on a controller then all the actions defined in it will be validated to check for any possible issue.
How to handle edge cases?
Say suppose, in the comments section of your applications, you would like to allow your users to submit a comment in HTML format. Then, by default the same error will be encountered. If in case, you want to disable this validation check, then this can be done using this attribute’s constructor method:
public ValidateInputAttribute(bool enableValidation)
{}
To disable the validation, we just need to pass false to the constructor as shown below:
// this applies to all the actions in this controller
[ValidateInput(false)]
public class BlogController : Controller {
}
// this applies to just this action
[ValidateInput(false)]
[HttpPost]
public ActionResult Comments(CommentInfo commentInfo){
}
Like any action filter, this filter can also be registered globally in your application but that is not good for security reasons discussed above as this will make your application prone to risk.
By disabled the input validation, user can now submit comment that has HTML formatted content.
Wait, there is a catch here!!!
By simply disabled the input validation at any level instructs the framework to follow this on all the properties of the model that is posted. As per the example above, we are just interested to allow say the `CommentBody` property to be formatted in HTML and not for all the members defined in `CommentInfo`. To be at safe side, for such scenarios, the framework also provides `AllowHTMLAttribute` class.
Allows a request to include HTML markup during model binding by skipping request validation for the property. (It is strongly recommended that your application explicitly check all models where you disable request validation in order to prevent script exploits.)
– MSDN
For the comments scenario, we can remove the ValidateInput call from controller & action and just change the model definition of `CommentInfo` type to be:
public class CommentInfo{
[AllowHtml]
[Display(Name = "Comment")]
public string CommentBody { get; set; }
}
This is the best way to tackle such situation. `AllowHtml` is good to target individual properties which is an explicit declaration and altogether, it’s more secure than the ValidateInput attribute as the latter disabled the validation on all the members defined in model/type. You now know how to use 2 of the other attributes that are available in ASP.NET MVC framework.
