Request Validation Mode in ASP .NET 4.5
Today I was examining request validation mode in ASP.NET 4.5 and observed some interesting behavior while using it with server control. With ASP.NET 4.5, Request Validation Mode introduced two new features called deferred or lazy request validation and access to unvalidated data.
Before ASP.NET 4.5, request validation was triggered either for each and every request data in beginning phase of request processing or if it is disabled then it triggers for none of them. In ASP.NET 4.5, lazy request validation feature is introduced which ensure that only required request data are validated only when it is accessed by code. To enable lazy request validation set requestValidationMode attribute to 4.5 in httpRuntime element in web.config.
<httpRuntime requestValidationMode="4.5" />
Once we set request validation mode to 4.5, request validation will be triggered for only request data which is accessed by code and only when it is actually executed by code. For e.g. If Request.Form["comment"] is accessed within button click event then only comment field will be validated when button click event fire if user does not click on button then it will not validate.
Another new feature introduced in request validation is that access to unvalidated data. In previous version of ASP.NET it was not possible to bypass request validation for selected request data. It was possible to disable request validation but there was no mechanism to access unvalidated data when request validation is enable. To enable this ASP.NET 4.5 introduced a new Unvalidated property within HttpRequest class which give access to request data without triggering request validation. For e.g. Request.Unvalidated.Form["comment"] will return raw data entered by user without triggering request validation on comment field. To use unvalidated data, you must set request validation mode to 4.5 in web.config.
So this was all about new request validation mode introduced in ASP.NET 4.5. More information on this can be found here. In starting of post, I mentioned that I observed some interesting behavior while using it with server control. So observed behavior is as follow.
I have created new webform application which target 4.5 framework and configured web.config to use newly introduced request validation mode by setting requestValidationMode attribute to 4.5.
Afterward I placed one ASP.NET textbox control and button control on the page and pressed F5 to run application and I entered potentially harmful data in textbox for e.g. <b>ASP.NET 4.5</b> and clicking on button it throw an exception "A potentially dangerous Request.Form value was detected… " I was shocked as I did not expected this exception because I have set requestValidationMode to 4.5 and I have not accessed textbox anywhere in code still it was triggering request validation! To cross verify I updated ValidateRequest value to false in @page directive and it works fine.
To continue with my experiment, i have reverted ValidateRequest value to again true in @page directive and added one HTML textbox control and entered same <b>ASP.NET 4.5</b> data into HTML textbox and clicked on button and it works fine because request validation mode was set to 4.5 and I have not accessed HTML textbox anywhere in the code. It was perfectly running fine with HTML textbox. Again to cross verify I updated request validation mode to 2.0 in web.config. and entered same potentially harmful data <b>ASP.NET 4.5</b> into HTML textbox and clicking on button it throw request validation exception "A potentially dangerous Request.Form value was detected… " this exception was expected because request validation mode was set to 2.0. Moving forward in my experiment, I again updated request validation mode to 4.5 in web.config and in button click event I accessed HTML textbox value with Request.Form["Text1"] and as expected after entering <b>ASP.NET 4.5</b> when clicked button it throw same exception because we accessed HTML textbox through code while request validation mode was set to 4.5.
So in short, what I observed is that while we have configured application to use request validation mode 4.5 at that time server control request validation triggers even if we have not accessed it anywhere in code. But the same thing does not apply to plain HTML control.
One more and last scenario to test. Again I added one more HTML textbox with runat server attribute and entered same data <b>ASP.NET 4.5</b> into this textbox and clicking on button again I shocked because it throw same exception even if request validation mode was set to 4.5 and I have not accessed it anywhere in code. But what I concluded is that it was due to runat server attribute because earlier we noticed same behavior with ASP.NET server textbox.
But still I was curious to know why request validation mode 4.5 is triggering request validation for server control. To dig more on it I examined stack trace for ASP.NET textbox and HTML textbox with runat server and what I observed is as follow.
Request validation exception generated by ASP.NET textbox
Request validation exception generated by HTML text with runat server
In above both stack trace, we can observe that along with server control lifecycle there is a call to Page.ProcessPostData method in stack trace and as name suggest that method might be processing posted data for server control only(as for HTML control request validation is not triggered so!) and as request validation mode 4.5 say it will trigger only when posted request data is accessed so this method might be accessing request data for server control and exception is thrown due to that access. I am not sure exactly that this is the only reason but it can be.
So what’s solution?
So what’s solution for this scenario? Whether it should validate server control or not while using request validation mode 4.5 and not accessing it through code? Ideally as per my personal view it should not validate server control because whether it is server control or plain HTML control, for client both are pure HTML controls and when requesting back to server it is the part of request data without differentiating that it is generated from ASP.NET server control or not.
Technically also it should not validate because when we set ValidateRequest value to false in @page directive at that time it is not validating server control so in this case also it should not validate server control during control lifecycle.
Textbox.Text and access to unvalidated data
So one more question is that while using request validation mode 4.5 at that time if user access Textbox.Text property then it should trigger request validation or not? Again as per my personal view and ideally it should because Textbox.Text property is exposing request data only so it should trigger request validation exception if it found potentially harmful data.
So now next question is that how to make access to unvalidated data through ASP.NET textbox? For that there can be new property called Textbox.UnValidatedText or something similar.
Any input on above is greatly appreciated.
Today itself I came across a post which illustrates use of Control.ValidateRequestMode property introduced in ASP.NET 4.5. I could not find any detail about this newly introduced property in the release note till I am updating this post. So I missed to consider it and might be my oversight :) so stay tuned to next post till that happy debugging ;)
NOTE: All view expressed here is my own personal and it is not of Microsoft or my current or previous employers.