Print

Input Validation
(Illustrated with ASP.net)

Cause and Exploits

  • Cause: failure to properly validate data at the entry and exit points of the application. 
  • Exploits: injection of malicious input such as code, scripting, commands, that can be interpreted/executed by different targets to exploit vulnerabilities: XSS/XFS injection, HTML-Splitting, SQL Injection, LDAP injection. XML injection, XPATH injection, file uploads attack, buffer overflow, etc. 

Basic Principles

  • "All input is evil  until proved otherwise." (M. Howard and D. LeBlanc, 2003)
  • "Strictly speaking JavaScript validation isn't validation -- it's input assistance. Anyone can bypass JavaScript; it's an aid, not a gate." (Collin Morris, 2007)

Type of Inputs

  • Based on directions, there are two types of data that can arise anywhere within an application's functionality to cause security concern:
    • User-supplied data: In some cases, an application imposes very stringent validation checks (e.g., username), while in other cases the application must tolerate a wider range of possible inputs (e.g., address field). Yet in some situations, an application (e.g., blogging on hacking) may need to accept completely arbitrary input from users.
    • Server-generated data: A typical application also receives numerous items of data (.e.g., cookies and hidden form values) that are generated by the server and sent to the client so that the client can transmit them back to the server on subsequent requests. In these cases, applications need to perform necessary data validation to assure that the data is authentic.
  • Data can also be categorized into the followings:
    • User interface elements (HTML form, URL box, hyperlink, etc.)
    • Configuration files (web.config)
    • Data files
    • HTTP headers
    • User identification (cookies)
    • Method parameters and property values

Basic Input Check (Filter)

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

Client-side Validation

  • Use server data validation controls (RegularExpressionValiator) and set values to ValidationExpression, ControlToValidate, and ErrorMessage properties. (demo)
  • Use Javascript and the "onsubmit" attribute of the "<form>" tag. (demo)
  • Note: The ASP.Net data validation controls can also do server-side validation by
  • The data validation controls are typically for validating required fields, length, format, data type, rage, and other simple filtering. These validation controls are not designed for preventing malicious activity.
  • Use a server control to call a Javascript validation: <asp:Button OnClientClick="return validateForm()" Text="Click Me" runat="server" />
  • ASP.NET Validation in Depth

Server-side Validation

  • Import the System.Text.RegularExpressions class.
  • Use the Regex class and the IsMatch() method (demo):
  • Dim reg As New Regex("^[a-zA-Z]{1,40}$")
    If Reg.IsMatch(tbName.Text, "^[a-zA-Z]{1,40}$") Then
        Response.Write("Valid input");   
    Else
        Response.Write("Invalid input");
    End If
  • Common metacharacters:
      [    the opening square bracket
      \    the backslash
      ^    the caret
      $    the dollar sign
      .    the period or dot
      |    the vertical bar or pipe symbol
      ?    the question mark
      *    the asterisk or star
      +    the plus sign
      (    the opening round bracket
      )    the closing round bracket
  • URL attack characters:
    < >   %3c and %3e (used in XSS)
    :       %3a (used in XSS with Javascript: )
            %27 , - %2D%2D, ; %3B (used in SQL injections)
    ../     %2E%2E%2F (used in directory transversal, file upload)
    `       %60 (used in command injections)
    /0     null) %00 (used in NULL strings)

Server scripting environment validation

  • When entering a value with angled brackets ("<aaa") into a text box on a .NET application, the following error is generated because it detected XSS-related data entry which looks like an HTML statement:
    A potentially dangerous Request.Form value was detected from the client
  • To disable request validation on a page, add the following ValidateRequest="false" directive to the existing "page" directive in the file:
    <%@ Page ValidateRequest="false" %>
        Or, the feature can be globally turned off in the the <system.web> section of the web.config file:
    <pages ValidateRequest="false" />
  • .Net 4.0 moved the validation up to before the BeginRequest event in the HTTP requests (include Web service calls and custom HTTP handlers), so that the validation gets executed before an ASPX page directive is parsed. Consequently, the ValidateRequest cannot be turned off at the page level. Instead, httpRuntime requestValidationMode="2.0" has to be specified in web.config. (see this stackoverflow post for more info.)
  • A general practice is to keep .NET request validation on site wide, unless the application absolutely requires so.

Sanitize Input

  • Sanitizing is about making potentially malicious data safe. It can be helpful when the range of input that is allowed cannot guarantee that the input is safe. This includes anything from stripping a null from the end of a user-supplied string to escaping out values so they are treated as literals.
  • In ASP.net, use Regex.Replace or HttpUtility.HtmlEncode 
  • Coding methods:
    • HtmlEncode: Untrusted input is used in HTML output except when assigning to an HTML attribute.
    • HtmlAttributeEncode: Untrusted input is used as an HTML attribute.
    • JavaScriptEncode: Untrusted input is used within a JavaScript context.
    • UrlEncode: Untrusted input is used in a URL (such as a value in a querystring).
    • XmlEncode: Untrusted input is used in XML output, except when assigning to an XML attribute.
    • XmlAttributeEncode: Untrusted input is used as an XML attribute
  • Problem with recursive tags
    • <script src= ...> can be sanitized to src=... by stripping the <script> tag.
    • <scr<scriptipt src=...">ipt> src=...> have to be sanitized recursively.

Accept Known Good (Whitelisting)

  • Employ a whiltelist of literal strings or patterns that is known to match only good input.
  • Allow data that matches the white list but block everything else. 
  • This approach is regarded as the most effective way of handling potentially malicious input.
  • When the application needs to take input (e.g., arrow brackets) that could potentially be harmful, the input should be decoded into normal characters, and then the certain characters that are allowed by the system can be encoded before the page is rendered again.
  • Internet standard  RFC 3986 defines 85 generic syntax to be used in URI formation.
    • 19 reserved characters:  ! * ' ( ) ; : @ & = + $ , / ? % # [ ]
    • 55 other characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~

Reject Known Bad (Blacklisting)

  • Employ a blacklist of literal strings or patterns that are known to be used in attacks.
  • Block any data that matches the blacklist but allow everything else.
  • This approach is regarded as the easiest but the least effective approach, because the set of possible bad data is potentially infinite and you will have to keep maintaining the list of "known bad" characters and patterns for as long as the input is in operation.
  • String comparison is the main logic behind the approach.
Constrain, Reject, and Sanitize (Microsoft)


(Source: Curphey et al., 2003)

Boundary Validation

(Source: Stuttard & Pinto, 2008)

 Boundary Input Validation OWASP

(Source: OWASP)

ASP.net Boundary
(source: Barry, 2010)

Reference