ASP.NET 2.0 Security Guidelines - Input/Data Validation

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley, Kishore Gopalan


Do Not Rely on ASP.NET Request Validation

The ASP.NET request validation feature performs basic input validation. Do not rely on it. Use it as an extra precautionary measure in addition to your own input validation. Only you can define what represents good input for your application.

Request validation is enabled by default. You can see this by examining the validateRequest attribute, which is set to true on the <pages> element in the Machine.config.comments file. Ensure that it is enabled for all pages except those that need to accept a range of HTML elements. If you need to disable it for a page, set the ValidateRequest attribute to false by using the @ Page directive.

Validate Input for Length, Range, Format, and Type

Do not trust input. An attacker passing malicious input can attempt SQL injection, cross-site scripting, and other injection attacks that aim to exploit your application's vulnerabilities. Check for known good data and constrain input by validating it for type, length, format, and range. For Web form applications that obtain input through server controls, use the ASP.NET validator controls, such as the RegularExpressionValidator, RangeValidator, and CustomValidator, to validate and constrain input. Check all numeric fields for type and range. If you are not using server controls, you can use regular expressions and the Regex class, and you can validate numeric ranges by converting the input value to an integer or double and then performing a range check.

Validate Input from All Sources Like QueryString, Cookies, and HTML Controls

Most Web applications accept input from various sources, including HTML controls, server controls, query strings, and cookies. Validate input from all of these sources to help prevent injection attacks. Use regular expressions to help validate input. The following example shows how to use the Regex class.

using System.Text.RegularExpressions ;

// Instance method:
Regex reg = new Regex(@"^[a-zA-Z'.\s]{1,40}$");
// Static method:
if (!Regex.IsMatch(Request.QueryString["Name"],@"^[a-zA-Z'.\s]{1,40}$")) 
  // Name does not match expression

If you cannot cache your regular expression for frequent use, you should use the static IsMatch method where possible for performance reasons, to avoid unnecessary object creation.

Do Not Rely on Client-Side Validation

Do not rely on client-side validation because it can be easily bypassed. For example, a malicious user could disable your client-side script routines by disabling JavaScript. Use client-side validation in addition to server-side validation to reduce round trips to the server and to improve the user experience.

Avoid User-Supplied File Name and Path Input

Where possible, avoid writing code that accepts user-supplied file or path input. Failure to do this can result in attackers coercing your application into accessing arbitrary files and resources. If your application must accept input file names, file paths, or URL paths, you need to validate that the path is in the correct format and that it points to a valid location within the context of your application.

File Names

Ensure that file paths only refer to files within your application's virtual directory hierarchy if that is appropriate. When checking file names, obtain the full name of the file by using the System.IO.Path.GetFullPath method.

File Paths

If you use MapPath to map a supplied virtual path to a physical path on the server, use the overloaded Request.MapPath method that accepts a bool parameter so that you can prevent cross-application mapping. The following code example shows this technique.

string mappedPath = Request.MapPath( inputPath.Text, 
                                     Request.ApplicationPath, false);
catch (HttpException)
 // Cross-application mapping attempted 

The final false parameter prevents cross-application mapping. This means that a user cannot successfully supply a path that contains ".." to traverse outside of your application's virtual directory hierarchy. Any attempt to do this results in an exception of type HttpException.

Do Not Echo Untrusted Input

Do not echo input back to the user without first validating and/or encoding the data. Echoing input directly back to the user makes your application susceptible to malicious input attacks, such as cross-site scripting.

If You Need to Write Out Untrusted Data, Encode the Output

If you write output that includes user input or data from a shared database or a local file that you do not trust, encode it. Echoing input directly back to the user makes your application vulnerable to cross-site scripting attacks. Encoding the data ensures that it is treated as literal text and not as script. You can use the HttpUtility.HtmlEncode method. Similarly, if you write URLs that might contain unsafe characters because they have been constructed from input data or data from a shared database, use HttpUtilty.UrlEncode to make them safe.

Note Make sure that you encode data at the last possible opportunity before the data is returned to the client.

Personal tools