About

I'm Mike Pope. I live in the Seattle area. I've been a technical writer and editor for over 35 years. I'm interested in software, language, music, movies, books, motorcycles, travel, and ... well, lots of stuff.

Read more ...

Blog Search


(Supports AND)

Feed

Subscribe to the RSS feed for this blog.

See this post for info on full versus truncated feeds.

Quote

The main thing you don't learn with a CS degree is how to develop software, although you will probably build up certain muscles in your brain that may help you later if you decide that developing software is what you want to do.

Joel Spolsky



Navigation





<January 2025>
SMTWTFS
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

Categories

  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  

Contact Me

Email me

Blog Statistics

Dates
First entry - 6/27/2003
Most recent entry - 9/4/2024

Totals
Posts - 2655
Comments - 2677
Hits - 2,722,187

Averages
Entries/day - 0.34
Comments/entry - 1.01
Hits/day - 346

Updated every 30 minutes. Last: 6:31 PM Pacific


  08:46 AM

A couple of us on the ASP.NET documentation team are working on a topic that describes how to disable request validation in ASP.NET. What do you think about the following draft? Any feedback welcome.



Request validation is a feature in ASP.NET that examines an HTTP request and determines whether it contains potentially dangerous content. In this context, potentially dangerous content is any HTML markup or JavaScript code in the body, header, query string, or cookies of the request. ASP.NET performs this check because markup or code found in the URL query string, cookies, or posted form values might have been added to the request for malicious purposes.

For example, if your site has a form where users enter comments, a malicious user could enter JavaScript code in a <script> element. Then when you display the page with the comment to other users, the browser would execute that JavaScript code as if it had been generated by your website. This is commonly referred to as a cross-site scripting (XSS) attack.

Request validation helps prevent this kind of attack. If ASP.NET detects any markup or code in a request, it throws a "potentially dangerous value was detected " error and stops page processing. The default error page looks like this (click to enlarge):



Request validation throws this exception when any HTML markup is detected, including harmless markup like <b> (bold) elements. This can be a problem if you want your application to accept HTML markup. For example, if your site lets users add comments, you might want to let users perform basic formatting using HTML tags that put text in bold or italics. In cases like these, you can disable request validation and check for malicious content manually, or you can customize request validation so that certain kinds of markup or script are accepted. For information about how to specify a custom error page instead of the default page shown above, see How to: Handle Application-Level Errors. For information about how to customize request validation, see the whitepaper Security Extensibility in ASP.NET 4 (PDF).

Disabling Request Validation

Security Note  If you disable request validation, you must check the user input yourself for dangerous HTML or JavaScript. For more information, see Manually Checking Requests later in this topic.

The method that you use to disable request validation depends on what type of ASP.NET web application you are working with:

Disabling Request Validation in ASP.NET Web Forms (4.0 or later)

You can disable request validation for an entire application, but this is not recommended. The recommendation is to selectively disable request validation only for the virtual paths or specific pages where you want to allow markup.

In either case, you must make two changes in the Web.config file. The first change is to set the requestValidationMode attribute of the <httpRuntime> element to "2.0". This makes request validation occur later in the sequence of request processing events. This setting is required for applications using ASP.NET 4 and later because for as of ASP.NET 4, request validation takes place earlier in the request life cycle than it did in previous versions of ASP.NET.
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
The following example shows how to make request validation occur later for a single page, in this case the Test.aspx page:
<location path="test.aspx">
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
</location>
The second change is to set validationRequest to false. For the application as a whole, you do this using the <pages> element in the Web.config file as shown in the following example. (This setting is effective only if you also set requestValidationMode="2.0".)
<configuration>
<system.web>
<pages validateRequest="false" />
</system.web>
</configuration>
For an individual page, you can set set validationRequest to false in the @ Page directive of the page, like this:
<@ Page validateRequest="false" %>

Disabling Request Validation in ASP.NET MVC

To disable request validation in an ASP.NET MVC application, you must change request validation to occur earlier in the sequence of request processing as explained earlier for ASP.NET Web Forms. In the Web.config file, make the following setting:
<system.web>
<httpRuntime requestValidationMode="2.0" />
</system.web>
In ASP.NET MVC, you can disable request validation for an action method, for a property, or for a field (input element) in a request. If you disable validation for an action method, you disable it for any requests that invoke that method — that is, all user input is allowed for any request that calls the action method. This is therefore the least secure way to disable request validation.

If you disable validation for a property, you allow user input for any reference to that property. If you disable validation for specific fields, you can control which request element (field) allows arbitrary user input.

To disable request validation for an action method, mark the method with the attribute ValidateInput(false), as shown in the following example:
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(string comment)
{
if (ModelState.IsValid)
{
// Etc.
}
return View(comment);
}
To disable request validation for a specific property, mark the property definition with the AllowHtml attribute:
[AllowHtml]
public string Prop1 { get; set; }
To disable request validation for a specific field in a request (for example, for an input element or query string value), call the System.Web.Helpers.Unvalidated method when you get the item, as shown in the following example:
var rawComment = Request.Unvalidated().Form["comment"];

Disabling Request Validation in ASP.NET Web Pages

To disable request validation for ASP.NET Web Pages, in code, call the Request.Unvalidated method and pass it the name of the field or other object that you want to bypass request validation for. The comments in the following code snippet indicate which lines of code cause request validation to be invoked and which ones do not.

Note  In ASP.NET Web Pages applications that do not also include Web Forms pages or MVC controllers, you do not need to make any changes in the Web.config file.
// Validated, throws error if input includes markup
var userComment = Request.Form["userInput"];

Request.Unvalidated("userInput"); // Validation bypassed
Request.Unvalidated().Form["userInput"]; // Validation bypassed

Request.QueryString["userPreference"]; // Validated
Request.Unvalidated().QueryString["userPreference"]; // Validation bypassed;

Manually Checking Requests

If you disable request validation, you must manually check the unvalidated user input for potentially dangerous input. Doing this is critical for the security of your application. However, it is not necessarily an easy task. If your code is flawed or if you forget to protect one page or one field, malicious users may eventually find and exploit that weakness.

In general, you should restrict as narrowly as possible the list of HTML tags that you will accept, and reject everything else. (This is sometimes referred as using a whitelist.)

If you are working with Web Forms pages, you can often use a third-party "rich text" control that lets users format text. These controls often have validation routines built in that permit only safe HTML. (If you use a control like this, make sure that it offers HTML safety.)

If you are not using a control like that, a very simple approach is to HTML-encode the user input, and then to selectively unencode just the HTML tags that you want to allow. This is practical if the tags you want to allow do not include attributes, such as <b>, <strong>, <i>, and <em>. The following example shows a way to encode and then selectively decode just the <b> and <i> tags.
// Encode the string input
StringBuilder sb = new StringBuilder(
HttpUtility.HtmlEncode(htmlInputTxt.Text));
// Selectively allow <b> and <i>
sb.Replace("&<b&>", "<b>");
sb.Replace("&</b&>", "</b>");
sb.Replace("&<i&>", "<i>");
sb.Replace("&</i&>", "</i>");
To allow more flexible HTML markup in the user input, you can use third-party libraries, such as the HTML Agility Pack that you can download from the CodePlex website, or the open-source OWASP Anti-Samy utility. For more information, see the example on the OWASP site of disabling request validation for ASP.NET.

Another approach is to use an alternative form of markup, like MarkDown, and then convert the user's text to valid and safe HTML. Many wikis use this approach. For more information about Markdown, see the Daring Fireball site.

See Also

New ASP.NET Request Validation Features for ASP.NET 4.5
ASP.NET MVC Tip #48 – Disable Request Validation

[categories]   ,

[6] |