ASP.NET 1.1 Security Guidelines - Input Validation

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Alex Mackman, Michael Dunner, Srinath Vasireddy, Ray Escamilla and Anandha Murukan


Contents

Constrain, Then Sanitize

Start by constraining input and check for known good data by validating for type, length, format, and range. Sometimes you also need to sanitize input and make potentially malicious input safe. For example, if your application supports free-format input fields, such as comment fields, you might want to permit certain "safe" HTML elements, such as bold and italic and strip out any other HTML elements. The following table summarizes the options that are available for constraining and sanitizing data:

Table Options for Constraining and Sanitizing Data

Requirement Options
Type checks .NET Framework type system. Parse string data, convert to a strong type, and then handle FormatExceptions, Regular expressions, Use ASP.NET RegularExpressionValidator control or Regex class.
Length checks Regular expressions, String.Length property
Format checks Regular expressions for pattern matching .NET Framework type system
Range checks ASP.NET RangeValidator control (supports currency, date, integer, double, and string data), Typed data comparisons

References


Use Regular Expressions for Input Validation

You can use regular expressions to restrict the range of valid characters, to strip unwanted characters, and to perform length and format checks. You can constrain input format by defining patterns that the input must match. ASP.NET provides the RegularExpressionValidator control and the Regex class is available from the System.Text.RegularExpressions namespace.

If you use the validator controls, validation succeeds if the control is empty. For mandatory fields, use a RequiredFieldValidator. Also, the regular expression validation implementation is slightly different on the client and server. On the client, the regular expression syntax of Microsoft JScript® development software is used. On the server, System.Text.RegularExpressions.Regex syntax is used. Since JScript regular expression syntax is a subset of System.Text.RegularExpressions.Regex syntax, it is recommended that JScript regular expression syntax be used to yield the same results on both the client and the server.

For more information about the full range of ASP.NET validator controls, refer to the .NET Framework documentation.

RegularExpressionValidator Control

To validate Web form field input, you can use the RegularExpressionValidator control. Drag the control onto a Web form and set its ValidationExpression, ControlToValidate, and ErrorMessage properties.

You can set the validation expression using the properties window in Microsoft Visual Studio .NET or you can set the property dynamically in the Page_Load event handler. The latter approach allows you to group together all of the regular expressions for all controls on the page.

Regex Class

If you use regular HTML controls with no runat="server" property (which rules out using the RegularExpressionValidator control), or you need to validate input from other sources such as query strings or cookies, you can use the Regex class either in your page class or in a validation helper method, possibly in a separate assembly. Some examples are shown later in this section.

Regular Expression Comments

Regular expressions are much easier to understand if you use the following syntax and comment each component of the expression using #. To enable comments, you must also specify RegexOptions.IgnorePatternWhitespace, which means that non-escaped white space is ignored.

Regex regex = new Regex(@"
                       ^           # anchor at the start
                      (?=.*\d)     # must contain at least one digit
                      (?=.*[a-z])  # must contain one lowercase
                      (?=.*[A-Z])  # must contain one uppercase
                      .{8,10}      # From 8 to 10 characters in length
                      $            # anchor at the end", 
                      RegexOptions.IgnorePatternWhitespace);


References


Sanitize Input

Sanitizing is about making potentially malicious data safe. It can be helpful when the range of allowable input cannot guarantee that the input is safe. This might include stripping a null from the end of a user-supplied string or escaping values so they are treated as literals. If you need to sanitize input and convert or strip specific input characters, use Regex.Replace.

Note Use this approach for defense in depth. Always start by constraining input to the set of known "good" values.

The following code strips out a range of potentially unsafe characters, including < > \ " ' % ; ( ) &.

private string SanitizeInput(string input)
{
 Regex badCharReplace = new Regex(@"([<>""'%;()&])");
 string goodChars = badCharReplace.Replace(input, "");
 return goodChars;
}

For more information about sanitizing free format input fields, such as comment fields, see "Sanitizing Free Format Input" under "Cross-Site Scripting," at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh10.asp?frame=true#c10618429_007

References


Validate HTML Controls

If you do not use server controls — that is, controls with the runat="server" attribute — and instead use regular HTML controls, you cannot use the ASP.NET validator controls. Instead, you can validate your Web pages' content by using regular expressions in the Page_Load event handler, as follows.

using System.Text.RegularExpressions;
. . .
private void Page_Load(object sender, System.EventArgs e)
{
 // Note that IsPostBack applies only for 
 // server forms (with runat="server")
 if ( Request.RequestType == "POST" ) // non-server forms
 {
   // Validate the supplied email address
   if( !Regex.Match(Request.Form["email"], 
        @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
        RegexOptions.None).Success) 
   {
     // Invalid email address
   }
   // Validate the supplied name
   if ( !RegEx.Match(Request.Form["name"],
        @"[A-Za-z'\- ]",
        RegexOptions.None).Success) 
   {
     // Invalid name
   }
 }
}


References


Validate Input Used for Data Access

If you are generating dynamic SQL queries based on user input, a SQL injection attack can inject malicious SQL commands that can be executed by the database. In a typical Web-based data access scenario, the following defense in depth strategy can be used:

  • Use regular expressions to constrain input within your page class.
  • Sanitize or reject input. For defense in depth, you can choose to use a helper method to strip null characters or other known bad characters.
  • Use parameterized stored procedures for data access to ensure that type and length checks are performed on the data used in SQL queries.

For more information about using parameters for data access and about writing secure data access code, see Chapter 14, "Building Secure Data Access." at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh14.asp

References


Validate Input Used For File I/O

In general, you should avoid writing code that accepts file input or path input from the caller. Instead, use fixed file names and locations when reading and writing data. This ensures that your code cannot be coerced into accessing arbitrary files. It also ensures that your code is not vulnerable to canonicalization bugs.

If you do need to accept input file names, there are two main challenges. First, is the resulting file path and name a valid file system name? Second, is the path valid in the context of your application? For example, is it beneath the application's virtual directory root?

To canonicalize the file name, use System.IO.Path.GetFullPath. To check that the file path is valid in the context of your application, you can use .NET code access security to grant the precise FileIOPermission to your code so that is able to access only files from specific directories. For more information, see the "File I/O" sections in Chapter 7, "Building Secure Assemblies" at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh07.asp and Chapter 8, "Code Access Security in Practice" at http://msdn.microsoft.com/library/en-us/dnnetsec/html/THCMCh08.asp

Using MapPath

If you use MapPath to map a supplied virtual path to a physical path on the server, use the overload of Request.MapPath that accepts a bool parameter so that you can prevent cross application mapping, as follows:

try
{
 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 so results in an exception of type HttpException.

Note Server controls can use the Control.MapPathSecure method to read files. This method requires that the calling code is granted full trust by code access security policy; otherwise an HttpException is thrown. For more information, see Control.MapPathSecure in the .NET Framework SDK documentation.

References

Personal tools