Input Validation


Like any application that accepts input data, Web services must validate the data that is passed to them to enforce business rules and to prevent potential security issues. Web methods marked with the WebMethod attribute are the Web service entry points. Web methods can accept strongly typed input parameters or loosely typed parameters that are often passed as string data. This is usually determined by the range and type of consumers for which the Web service is designed.

Strongly Typed Parameters

If you use strongly typed parameters that are described by the .NET Framework type system, for example integers, doubles, dates, or other custom object types such as Address or Employee, the auto-generated XML Schema Definition (XSD) schema contains a typed description of the data. Consumers can use this typed description to construct appropriately formatted XML within the SOAP requests that are sent to Web methods. ASP.NET then uses the System.Xml.Serialization.XmlSerializer class to deserialize the incoming SOAP message into common language runtime (CLR) objects. The following example shows a Web method that accepts strongly typed input consisting of built-in data types.

 [WebMethod] public void CreateEmployee(string name, int age, decimal salary) {...} 

In the preceding example, the .NET Framework type system performs type checks automatically. To validate the range of characters that are supplied through the name field, you can use a regular expression. For example, the following code shows how to use the System.Text.RegularExpressions.Regex class to constrain the possible range of input characters and also to validate the parameter length.

 if (!Regex.IsMatch(name, @"^[a-zA-Z'.`-\s]{1,40}$")) {   // Invalid name } 

For more information about regular expressions, see the "Input Validation" section in Chapter 10, "Building Secure ASP.NET Pages and Controls." The following example shows a Web method that accepts a custom Employee data type.

 using Employees;  // Custom namespace [WebMethod]     public void CreateEmployee(Employee emp) { ... } 

The consumer needs to know the XSD schema to be able to call your Web service. If the consumer is a .NET Framework client application, the consumer can simply pass an Employee object as follows :

 using Employees; Employee emp = new Employee(); // Populate Employee fields // Send Employee to the Web service wsProxy.CreateEmployee(emp); 

Consumer applications that are not based on the .NET Framework must construct the XML input manually, based on the schema definition provided by the organization responsible for the Web service.

The benefit of this strong typing approach is that the .NET Framework parses the input data for you and validates it based on the type definition. However, inside the Web method you might still need to constrain the input data. For example, while the type system confirms a valid Employee object, you might still need to perform further validation on the Employee fields. You might need to validate that an employee's date of birth is greater than 18 years ago. You might need to use regular expressions to constrain the range of characters that can be used in name fields, and so on.

For more information about constraining input, see the "Input Validation" section in Chapter 10, "Building Secure ASP.NET Pages and Controls."

Loosely Typed Parameters

If you use string parameters or byte arrays to pass arbitrary data, you lose many of the benefits of the .NET Framework type system. You must parse the input data manually to validate it because the auto-generated WSDL simply describes the parameters as string input of type xsd:string. You need to programmatically check for type, length, format, and range as shown in the following example.

 [WebMethod] public void SomeEmployeeFunction(string dateofBirth, string SSN) {     . . .   // EXAMPLE 1: Type check the date   try   {     DateTime dt = DateTime.Parse(dateofBirth).Date;   }   // If the type conversion fails, a FormatException is thrown   catch(FormatException ex)   {     // Invalid date   }       // EXAMPLE 2: Check social security number for length, format, and range   if(!Regex.IsMatch(empSSN,@"^\d{3}-\d{2}-\d{4}$",RegexOptions.None))   {       // Invalid social security number   } } 

XML Data

In a classic business-to-business scenario, it is common for consumers to pass XML data that represents business documents such as purchase orders or sales invoices. The validity of the input data must be programmatically validated by the Web method before it is processed or passed to downstream components .

The client and the server have to establish and agree on a schema that describes the XML. The following code fragment shows how a Web method can use the System.Xml.XmlValidatingReader class to validate the input data, which, in this example, describes a simple book order. Notice that the XML data is passed through a simple string parameter.

 using System.Xml; using System.Xml.Schema;     [WebMethod] public void OrderBooks(string xmlBookData) {   try   {     // Create and load a validating reader     XmlValidatingReader reader = new XmlValidatingReader(xmlBookData,                                                          XmlNodeType.Element,                                                          null);     // Attach the XSD schema to the reader     reader.Schemas.Add("urn:bookstore-schema",                        @"http://localhost/WSBooks/bookschema.xsd");     // Set the validation type for XSD schema.     // XDR schemas and DTDs are also supported     reader.ValidationType = ValidationType.Schema;     // Create and register an event handler to handle validation errors     reader.ValidationEventHandler += new ValidationEventHandler(ValidationErrors);     // Process the input data     while (reader.Read())     {       . . .     }     // Validation completed successfully   }   catch   {    . . .   } }     // Validation error event handler private static void ValidationErrors(object sender, ValidationEventArgs args) {   // Error details available from args.Message   . . . } 

The following fragment shows how the consumer calls the preceding Web method:

 string xmlBookData = "<book  xmlns='urn:bookstore-schema'                          xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +                      "<title>Building Secure ASP.NET Applications</title>" +                      "<isbn>0735618909</isbn>" +                      "<orderQuantity>1</orderQuantity>" +                      "</book>"; BookStore.BookService bookService = new BookStore.BookService(); bookService.OrderBooks(xmlBookData)); 

The preceding example uses the following simple XSD schema to validate the input data.

 <?xml version="1.0" encoding="utf-8" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"             xmlns="urn:bookstore-schema"             elementFormDefault="qualified"             targetNamespace="urn:bookstore-schema">   <xsd:element name="book" type="bookData"/>   <xsd:complexType name="bookData">     <xsd:sequence>       <xsd:element name="title" type="xsd:string" />       <xsd:element name="isbn" type="xsd:integer" />       <xsd:element name="orderQuantity" type="xsd:integer"/>     </xsd:sequence>   </xsd:complexType> </xsd:schema> 

The following table shows additional complex element definitions that can be used in an XSD schema to further constrain individual XML elements.

Table 12.1: XSD Schema Element Examples

Description

Example

Using regular expressions to constrain XML elements

 <xsd:element name="  zip  ">   <xsd:simpleType> <xsd:restriction base="xsd:string">      <xsd:pattern value="\d{5}(-\d{4})?" />     </xsd:restriction>   </xsd:simpleType> </xsd:element> 

Constraining a decimal value to two digits after the decimal point

 <xsd:element name="  Salary  ">   <xsd:simpleType>     <xsd:restriction base="xsd:decimal">       <xsd:fractionDigits value="2" />     </xsd:restriction>   </xsd:simpleType> </xsd:element> 

Constraining the length of an input string

 <xsd:element name="  FirstName  ">   <xsd:simpleType>     <xsd:restriction base="xsd:string">       <xsd:maxLength value="50" />       <xsd:minLength value="2" />     </xsd:restriction>   </xsd:simpleType> </xsd:element> 

Constraining input to values defined by an enumerated type

 <xsd:element name="  Gender  ">   <xsd:simpleType>     <xsd:restriction base="xsd:string">       <xsd:enumeration value="Male" />       <xsd:enumeration value="Female" />     </xsd:restriction>   </xsd:simpleType> </xsd:element> 

For more information, see Microsoft Knowledge Base articles:

  • 307379, "How To: Validate an XML Document by Using DTD, XDR, or XSD in Visual C# .NET."

  • 318504, "How To: Validate XML Fragments Against an XML Schema in Visual C#.NET."

SQL Injection

SQL injection allows an attacker to execute arbitrary commands in the database using the Web service's database login. SQL injection is a potential issue for Web services if the services use input data to construct SQL queries. If your Web methods access the database, they should do so using SQL parameters and ideally , parameterized stored procedures. SQL parameters validate the input for type and length, and they ensure that the input is treated as literal text and not executable code. For more information about this and other SQL injection countermeasures, see the "Input Validation" section in Chapter 14, "Building Secure Data Access."

Cross-Site Scripting

With cross-site scripting (XSS), an attacker exploits your application to execute malicious script at the client. If you call a Web service from a Web application and send the output from the Web service back to the client in an HTML data stream, XSS is a potential issue. In this scenario, you should encode the output received from the Web service in the Web application before returning it to the client. This is particularly important if you do not own the Web service and it falls outside the Web application's trust boundary. For more information about XSS countermeasures, see the "Input Validation" section in Chapter 10, "Building Secure ASP.NET Pages and Controls."




Improving Web Application Security. Threats and Countermeasures
Improving Web Application Security: Threats and Countermeasures
ISBN: 0735618429
EAN: 2147483647
Year: 2003
Pages: 613

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net