Security is always the one of the greatest concerns of Applications and when it comes to web applications, they are more prone to security breach. All the web technologies provides many features that are used to write secured web applications.
Here In this post, I am going to discuss Request Validation feature, mainly focusing ASP.NET 4.5 version.
Request validation introduced since ASP.NET 1.1 is available. By default it is enabled and it prevents to accept un-encoded HTML/XML etc from Client to server. It validates all the data that is passed from client to server. It can be any form like
- Form Collection
- Server variables
This helps to avoid script injection attacks. So it is always recommended to validate all the data that is passed from client to server because it can be malicious code and can be harmful the application.
Although, if we are sure that this situation would not arise, it can be disabled at application level or page level so no request will get validated. But this is not the case every time. On some occasions, we may need to allow users to enter some html, xml etc.. data . In this case, we need to partially validate the request.
There are several scenarios where we need to turn off the request validation just because of some specific data we don’t need to get validated. It leads us to write less secure code because we are the whole request goes to unvalidated. There are scenarios like in blog sites where we normally allow the user to write html , xml etc as input
Till ASP.NET 4.0, we have option to disable the request validation in the entire application or can be done page by page. But till now we did not have option to partially validate the page. ASP.NET 4.5 enables us to validate some specific part of the request.
ASP.NET 4.5 provides us two features.
- Selectively un-validate the request
- Deferred or lazy validation
How to allow partially unvalidated request in asp.net 4.5
(Note : I have VS11 beta version for this post)
I have created a sample application and have two textboxes – txtValidate and txtunValidate, with a submit button.
Let’s have a use case that I want to validate txtValidate but not txtunValidate. You must remember that this was not possible with earlier version of ASP.NET.I’ll also discuss it in detail later. To use this feature , you must set
requestValidationMode as 4.5 in web.config like
<httpruntime requestvalidationmode="4.5" />
Apart from this, ASP.NET 4.5 added one more property
ValidateRequestMode with input controls. And it can have the following values
- Enabled: Request validation is enabled for the control. Bydefault it is enabled
- Disabled: Input values for this control would not be validated
- Inherit: Property value will be inherited from parent
So let’s proceed with sample, and as I don’t want to validate txtunValidate so I need to set ValidateRequestMode attribute as disabled like
Now Let’s run the code.
And as you can see I’ve put some script tag in txtunValidate and it worked fine. But let us remove the requestValidationMode from web.config and try to submit the same input again.
and see it gave the
HttpRequestValidationException exception and got the above screen. Now lets again put the attribute requestValidationMode in web.config and try to put some script in txtValidate and submit. It’ll show you the same exception again as expected. So here you can see, ASP.NET 4.5 enables us to selectively validate the request.
Deferred or lazy validation
This is also introduced in asp.net 4.5 and I’ll say that above feature is just a corollary of this feature.
To provide these features, Microsoft has done some major changes in the way Request Validation feature got implemented in earlier version of ASP.NET. As we know, to process a request, ASP.NET creates an instance of HTTPContext which holds the instance of HTTPRequest and HTTPResponse with other required data. All the input data that is passed from client to server, it is posted in form collection, querystring etc.. ASP.NET validates every data that is passed from client to server.
Actually in ASP.NET 4.5, whenever the data is accessed from the request it gets validated. Like when we access the form collection to some input as
Request.Form[uniqueId] the validation triggers. To provide selective validation, Microsoft has introduced a new collection property named as
Unvalidated in the HTTPRequest class. This contains all the data that is passed from client to server like cookies, form collection, querystring etc as
Now the same data is available at two places. In
UnValidated collection and normal in HTTPRequest. When we set the
ValidateRequestMode is disabled, the data is accessed from
UnValidated collection else normal request.
UnValidated collection don’t trigger any validation while other one triggers. I’ll show you a demo later.
In earlier version of ASP.NET 1.1/2.0/3.5, Request validation is done at earlier level of page processing. There were also some good amount of changes took place in ASP.NET 4.0, which provides us the feature to validate the non-ASP.NET resources as well which was not available earlier.
Under the hood
I have the same application and I have removed the requestValidationMode attribute from web.config and putting some html tags as I did above example and pressed submit. So I got the
Now let’s put the requestValidationMode as 4.5 and try the same as above. I have removed the disable attribute. Again I got the same exception as below
But if we examine the circled part of the stacktrace, we can easily Identify that in 4.5, the validation exception got thrown from TextBox’s
Let’s do some experiment to examine this. I have made two case studies for this.
Case Study 1
As we all know the ASP.NET Page LifeCycle as
As you can see, here
LoadPostData is a part of PageLife Cycle and comes after LoadViewState. All of the Input control’s data don’t get wiped off during postback even if viewstate is not enabled for that control. I have written a post on it. You can view this here.
So this is the
LoadPostData method that is responsible to get the data from Form collection and assign it to the control. As I said, Now asp.net 4.5, validates the input only when you access the data from form collection. That’s why if you look the stacktrace then it is visible that the exception is thrown from
LoadPostData method only and page life cycle is the last stage of ASP.NET Request Processing.
Now lets try to have an clarification using a demo. As I mentioned, in ASP.NET 4.5, the validation triggers only when the data is accessed and the data is accessed at LoadPostData for input controls. So lets create a custom textbox. For this I’ll override LoadPostData method and will do nothing in that. It means that the data would not be accessed for the customTextBox at LoadPostData. So even if the ValidationMode is enabled for the CustomtextBox, it wont be fired. Lets see this
I have created a CustomtestBox and overridden the LoadPostData method as
public class CustomTextBox : System.Web.UI.WebControls.TextBox
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
You can see, I have just returned false in the
LoadPostData method. Now I have used my CustomTextBox at my aspx page as
Now set the requestValidationMode as 4.5 in web.config and enter some script tag and submit.
You would not get any error even RequestValidation is enabled. This proves the validation fires only when data is accessed from the form collection.
Case Study 2
Here I’ll also try to prove the same as above. I have already shown above that How the new UnValidated property of Context holds all the data including form collection, querystring, cookies etc. So whenever the data is accessed from the
UnValidated collection, the validation is not fired. But when it is accessed from the normal form collection, validation gets fired.
So here I am going to use again the earlier sample. In that example I had two textboxes and a submit button. Here the change is that at server side, instead of accessing the data form
txtValidate.Text, I’ll be accessing the data from FormCollection. So I’ll set the the ValidateRequestMode as disabled for both the textbox and will try to get the data one will be form normal Form Collection and another is from Unvalidated’s form collection as
protected void Button1_Click(object sender, EventArgs e)
string textValidated = this.Context.Request.Unvalidated.Form[txtValidate.UniqueID];
string textUnValidated = this.Context.Request.Form[txtunValidate.UniqueID];
Now lets enter some html tags in both the textboxes and submit the page using debugger as
Oh!! see even we have disabled the validation, even in that situation when data is accessed from normal Form collection the validation is fired.
This again proves the validation is fired only when the data is acessed and when the ValidateRequestMode is set as disabled it is accessed from the UnValidated property.
Hope you all have enjoyed the post. Do share your precious feedback.