Validation Guidelines

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies.
This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

There are two types of validation. They are:

  • Server-side validation. This type of validation takes place on the server, during a postback.
  • Client-side validation. This type of validation takes place in the browser and does not require a postback.

Choosing the Validation Type

Web client developers have to choose the validation type that best suits their scenarios. When selecting the validation type, consider the following guidelines:

  • If providing immediate feedback to the user about validation results is critical, use client-side validation.
  • If your validation requires resources in the server, use server-side validation. Also, for security reasons, you should always perform server-side validation.

Using Client-Side Validation

Because client-side validation takes place in the browser, it does not require a round trip to the server. This means that client-side validation enhances the UI’s responsiveness because the user does not need to wait for the server to respond.

Note

Malicious users can easily bypassclient-side validation to launch attacks against your application. For more information, see Validation Security Guidelines..

Using Server-Side Validation

Because server-side validation takes place in the server, it requires round trips between the client and the server. Developers must perform server-side validation when the validation process requires resources on the server, such as a list of valid values stored in a database, against which it can compare the input. Server-side validation also improves security because it is difficult to bypass it. In cases where client-side and server-side validation types are used together, the validation on the server acts as a second barrier that stops malicious users who bypass the client-side validation (for more information, see the section, Validation Security Guidelines).

If improving UI responsiveness is critical in your application, consider combining server-side validation with client-side validation.

ASP.NET Validation Controls

The Web Forms framework includes a set of validation server controls that provide an easy-to-use and powerful way to check input forms for errors and, if necessary, display messages to the user.

You add validation controls to a Web Forms page the same ways as other server controls. There are controls for specific types of validation, such as range checking or pattern matching, plus a RequiredFieldValidator control that ensures that a user does not skip an entry field. You can attach more than one validation control to an input control. For example, you might specify that an entry is required and that it must contain a specific range of values.

Validation controls work with a limited subset of HTML and Web server controls. For each control, a specific property contains the value to be validated. The validation controls always perform validation checking in server code; therefore, they require a full-page round trip. However, if the user is working with a browser that supports DHTML, the validation controls can also perform validation using client script. With client-side validation, any errors are detected on the client when the form is submitted to the server. If any of the validators are found to be in error, the submission of the form to the server is canceled and the validator's Text property is displayed. This permits the user to correct the input before submitting the form to the server. Field values are revalidated immediately after the field containing the error loses focus, thus providing the user with a rich, interactive validation experience.

The ASP.NET validation framework includes a control named CustomValidator. This control enables users to perform validation that is not included in another validation control or to perform validation that requires access to information on the server, such as a database or Web service. When developers use a CustomValidator, they have to provide a server validation function that performs the validation logic. If you add a CustomValidator with only a server validation function defined, client-side validation will not be performed. The CustomValidator does not perform validations as users tab between fields, and it requires a round trip to the server to perform its validation. If you are using a CustomValidator to perform a check that does not need any information that lives on the server, you can also have your validator fully participate in client-side validation by implementing a client validation function. It is assumed that if you provide a client validation function, it should ideally perform exactly the same checks as your server validation handler. Failing that, it should perform a subset of that verification. Make sure you do not have a client validation function that does more verifications than are performed on the server, because hackers will be able to easily bypass it.

Understanding the Enterprise Library Validation Application Block

The Enterprise Library Validation Application Block provides a library of classes, named validators, that contain code for validating .NET Framework data types. For example, one validator checks for null strings and another validator checks that a number falls within a specified range. The Validation Application Block allows you to easily validate objects. In many situations, you can validate an object with a single line of code. The following example shows how to associate a validator with an object and how to validate that object.

using Microsoft.Practices.EnterpriseLibrary.Validation;
using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
public class Customer
{
    [StringLengthValidator(0, 20)]
    public string CustomerName;

    public Customer(string customerName)
    {
        this.CustomerName = customerName;
    }
}

public class MyExample
{
    public static void Main() 
    {
        Customer myCustomer = new Customer("A name that is too long");
        ValidationResults r = Validation.Validate<Customer>(myCustomer);
        if (!r.IsValid)
        {
            throw new InvalidOperationException("Validation error found.");
        }
    }
}

You can easily integrate the Validation Application Block with ASP.NET applications. For example, you can use the application block to validate information a user enters into a Web form.

The Validation Application Block includes the custom ASP.NET control named PropertyProxyValidator. Developers use this control on Web pages to validate an ASP.NET control's value using the Validation Application Block validators. The PropertyProxyValidator class acts as a wrapper that links a control to a validator in an application-level class.

Note

Note: For more information about integrating the Validation Application Block with ASP.NET, see the Enterprise Library.

Selecting Validation Controls

Developers of Web client applications have to decide what validation controls to use to perform the chosen validation type. The following guidelines will help you choose the best validation controls for your particular scenario:

  • If you need to reuse validation logic across screens, applications and/or tiers, use the Enterprise Library Validation Application Block.
  • If you need to reuse validation logic across different pages, consider creating a custom validation class that extends the ASP.NET BaseValidator class.
  • When performing client-side validation, consider ASP.NET validation controls as the first option. If ASP.NET validation controls do not address your requirements, write custom client script.
  • If you need to perform cross-field validation in the server and UI responsiveness is important in your scenario, consider using a CustomValidator control inside an UpdatePanel control.

Using the Validation Application Block for Validation

If encapsulation and reutilization of the validation logic is a primary concern in your system, consider defining the validation logic with the Enterprise Library Validation Application Block and using the PropertyProxyValidator control in your Web pages. By using the application block, you can define validation rules in one place and reuse them across screens, layers and tiers of your applications. The PropertyProxyValidator control requires a round trip to the server; therefore, to improve the UI’s responsiveness, you can combine PropertyProxyValidator controls with ServerSideValidationExtender extenders.

Using Custom Classes for Validation

If different pages of your Web application need to perform the same validation logic, consider creating a new validator control. To create a new validator, derive it from the BaseValidator class exposed by the ASP.NET framework. By doing this, you will encapsulate the validation logic in a reusable control that you can include in multiple pages.

For more information about the BaseValidator class, see BaseValidator Class.

Using ASP.NET Validation Controls

To perform client-side validation, consider using the built-in ASP.NET validation controls as the first option. These controls always perform server-side validation independently of the client-side validation; therefore, security is improved. If the ASP.NET validation controls do not address your requirements, write custom client script.

Using Custom Validators

If you need to perform cross-field validation in the server, consider using a CustomValidator control inside an UpdatePanel control. By placing the validator inside an UpdatePanel, you avoid full postbacks; therefore, the UI’s responsiveness improves.

Validation Security Guidelines

With responsive Web user interfaces, developers have more choices of how, when, and where to validate information entered by the user. To improve security, consider the following guidelines:

  • Do not rely on client-side validation.
  • Validate input for length, range, format, and type.
  • Validate input from all sources, such as query strings, cookies, and HTML controls.
  • Do not rely on ASP.NET request validation.
  • Avoid user-supplied file name and path input.
  • Do not echo suspect input.
  • If you need to write out suspect data, encode the output.

The next sections describe each of these guidelines.

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 the JavaScript or could generate a harmful HTTP request that simulates a post from your Web site.

Use client-side validation in addition to server-side validation to reduce round trips to the server and to improve the user experience.

Validate Input for Length, Range, Format, and Type

Do not trust the input. An attacker can attempt SQL injection, cross-site scripting, and other injection attacks that exploit your application's vulnerabilities. Check for known good data and constrain the 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 validators. Check all numeric fields for type and range. If you are not using server controls, you can use regular expressions and the Regex class. You can validate numeric ranges by first converting the input value to an integer or double and then performing a range check.

Validate Input from All Sources, such as Query Strings, 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}$");
Response.Write(reg.IsMatch(Request.QueryString["Name"]));

// 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 ASP.NET Request Validation

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

By default, request validation is enabled. 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.

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 allows attackers to substitute 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 refer only 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.

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

Do Not Echo Suspect 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 Suspect 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 to encode the data. 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 the HttpUtilty.UrlEncode method to encode them.

Note

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

For more information about how to improve the security of your application, see the following topics on MSDN: