Overview

Web services are used by an increasing number of companies as they expose products and services to customers and business partners through the Internet and corporate extranets. The security requirements for these service providers are of paramount importance. In some cases, primarily intranet or extranet scenarios where you have a degree of control over both endpoints, the platform-based security services provided by the operating system and Internet Information Services (IIS) can be used to provide point- to-point security solutions. However, the message based architecture of Web services and the heterogeneous environments that span trust boundaries in which they are increasingly being used pose new challenges. These scenarios require security to be addressed at the message level to support cross-platform interoperability and routing through multiple intermediary nodes.

Web Services Security (WS-Security) is the emerging security standard designed to address these issues. Microsoft has released Web Services Enhancements 1.0 for Microsoft .NET (WSE), which supports WS-Security and a related family of emerging standards. WSE allows you to implement message level security solutions including authentication, encryption and digital signatures.

NoteThe specifications and standard supported by WSE are evolving and therefore the current WSE does not guarantee it will be compatible with future versions of the product. At the time of this writing, interoperability testing is under way with non-Microsoft toolkits provided by vendors including IBM and VeriSign.

Threats and Countermeasures

To build secure Web services, know the associated threats. The top threats directed at Web services are:

Unauthorized access

Parameter manipulation

Network eavesdropping

Disclosure of configuration data

Message replay

Figure 1 shows the top threats and attacks directed at Web services.

Figure 1. Main Web services threats

Unauthorized Access

Web services that provide sensitive or restricted information should authenticate and authorize their callers. Weak authentication and authorization can be exploited to gain unauthorized access to sensitive information and operations.

Vulnerabilities

Vulnerabilities that can lead to unauthorized access through a Web service include:

No authentication used

Passwords passed in plaintext in SOAP headers

Basic authentication used over an unencrypted communication channel

Countermeasures

You can use the following countermeasures to prevent unauthorized access:

Use password digests in SOAP headers for authentication.

Use Kerberos tickets in SOAP headers for authentication.

Use X.509 certificates in SOAP headers for authentication.

Use Windows authentication.

Use role-based authorization to restrict access to Web services. This can be done by using URL authorization to control access to the Web service file (.asmx) or at the Web method level by using principal–permission demands.

Parameter Manipulation

Parameter manipulation refers to the unauthorized modification of data sent between the Web service consumer and the Web service. For example, an attacker can intercept a Web service message, perhaps as it passes through an intermediate node en route to its destination; and can then modify it before sending it on to its intended endpoint.

Vulnerabilities

Vulnerabilities that can make parameter manipulation possible include:

Messages that are not digitally signed to provide tamperproofing

Messages that are not encrypted to provide privacy and tamperproofing

Countermeasures

You can use the following countermeasures to prevent parameter manipulation:

Digitally sign the message. The digital signature is used at the recipient end to verify that the message has not been tampered with while it was in transit.

Encrypt the message payload to provide privacy and tamperproofing.

Network Eavesdropping

With network eavesdropping, an attacker is able to view Web service messages as they flow across the network. For example, an attacker can use network monitoring software to retrieve sensitive data contained in a SOAP message. This might include sensitive application level data or credential information.

Vulnerabilities

Vulnerabilities that can enable successful network eavesdropping include:

Credentials passed in plaintext in SOAP headers

No message level encryption used

No transport level encryption used

Countermeasures

You can use the following countermeasures to protect sensitive SOAP messages as they flow across the network:

Use transport level encryption such as SSL or IPSec. This is applicable only if you control both endpoints.

Encrypt the message payload to provide privacy. This approach works in scenarios where your message travels through intermediary nodes route to the final destination.

Disclosure of Configuration Data

There are two main ways in which a Web service can disclose configuration data. First, the Web service may support the dynamic generation of Web Service Description Language (WSDL) or it may provide WSDL information in downloadable files that are available on the Web server. This may not be desirable depending on your scenario.

NoteWSDL describes the characteristics of a Web service, for example, its method signatures and supported protocols.

Second, with inadequate exception handling the Web service may disclose sensitive internal implementation details useful to an attacker.

Vulnerabilities

Vulnerabilities that can lead to the disclosure of configuration data include:

Unrestricted WSDL files available for download from the Web server

A restricted Web service supports the dynamic generation of WSDL and allows unauthorized consumers to obtain Web service characteristics

Weak exception handling

Countermeasures

You can use the following countermeasures to prevent the unwanted disclosure of configuration data:

Authorize access to WSDL files using NTFS permissions.

Remove WSDL files from Web server.

Disable the documentation protocols to prevent the dynamic generation of WSDL.

Capture exceptions and throw a SoapException or SoapHeaderException—that returns only minimal and harmless information—back to the client.

Message Replay

Web service messages can potentially travel through multiple intermediate servers. With a message replay attack, an attacker captures and copies a message and replays it to the Web service impersonating the client. The message may or may not be modified.

Vulnerabilities

Vulnerabilities that can enable message replay include:

Messages are not encrypted

Messages are not digitally signed to prevent tampering

Duplicate messages are not detected because no unique message ID is used

Attacks

The most common types of message replay attacks include:

Basic replay attack. The attacker captures and copies a message, and then replays the same message and impersonates the client. This replay attack does not require the malicious user to know the contents of the message.

Man in the middle attack. The attacker captures the message and then changes some of its contents, for example, a shipping address, and then replays it to the Web service.

Countermeasures

You can use the following countermeasures to address the threat of message replay:

Use an encrypted communication channel, for example, SSL.

Encrypt the message payload to provide message privacy and tamperproofing. Although this does not prevent basic replay attacks, it does prevent man in the middle attacks where the message contents are modified before being replayed.

Use a unique message ID or nonce with each request to detect duplicates, and digitally sign the message to provide tamperproofing.

NoteA nonce is a cryptographically unique value used for the request.

When the server responds to the client it sends a unique ID and signs the message, including the ID. When the client makes another request, the client includes the ID with the message. The server ensures that the ID sent to the client in the previous message is included in the new request from the client. If it is different, the server rejects the request and assumes it is subject to a replay attack.

The attacker cannot spoof the message ID, because the message is signed. Note that this only protects the server from client-initiated replay attacks using the message request, and offers the client no protection against replayed responses.

Design Considerations

Before you start to develop Web services, there are a number of issues to consider at design time. The key security considerations are:

Authentication requirements

Privacy and integrity requirements

Resource access identities

Code access security

Authentication Requirements

If your Web service provides sensitive or restrictive information, it needs to authenticate callers to support authorization. In Windows environments, you can use Windows authentication. However, where you are not in control of both endpoints, WSE provides authentication solutions that conform to the emerging WS-Security standard. WSE provides a standard framework for using SOAP headers to pass authentication details in the form of user names and passwords, Kerberos tickets, X.509 certificates, or custom tokens. For more information, see the "Authentication" section later in this module.

Privacy and Integrity Requirements

If you pass sensitive application data in Web service requests or response messages, consider how you can ensure that they remain private and unaltered while in transit. WSE provides integrity checking through digital signatures, and it also supports XML encryption to encrypt sensitive elements of the entire message payload. The advantage of this approach is that it is based on the emerging WS-Security standard and that it provides a solution for messages that pass through multiple intermediate nodes.

The alternative is to use transport level encryption through SSL or IPSec channels. These solutions are only appropriate where you are in control of both endpoints.

Resource Access Identities

By default, ASP.NET Web services do not impersonate, and the least privileged ASPNET process account is used for local and remote resource access. You can use this ASPNET process account to access remote network resources such as SQL Servers that require Windows authentication, by creating a mirrored local account on the database server.

NoteOn Windows Server 2003, the Network Service account is used by default to run Web services.

Code Access Security

Consider the trust level defined by security policy in your target deployment environment. Your Web service's trust level, defined by its <trust> element configuration, affects the types of resources that it can access and the other privileged operations it can perform.

Also, if you call a Web service from an ASP.NET Web application, the Web application's trust level determines the range of Web services it can call. For example, a Web application configured for Medium trust, by default, can only call Web services on the local computer.

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

}

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.

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",

@"

// 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=' +

"<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="

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 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>

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.