Security is a major requirement for Web services that is not addressed by the SOAP specification. WS-Security leverages other specifications, like XML Signature and XML Encryption, to describe a set of XML-based functionalities that can be used to secure SOAP messages. In this chapter, I will discuss some of the potential security vulnerabilities inherent in Web services, as well as ways to address these vulnerabilities. I will take an in depth look at the WS-Security specification and the security features that it prescribes. Finally, I will discuss Microsoft s support of the WS-Security specification provided by the Microsoft Web Services Enhancements (WSE), and I will demonstrate how to use this product to secure a .NET Web service.
Please note that this chapter is not meant to be a complete resource for all .NET programming security issues. For an excellent general treatise on creating secure applications and services, you ll want to read Writing Secure Code , Second Edition, by Michael Howard and David LeBlanc (Microsoft Press, 2002).
It has been widely acknowledged that security issues have posed a major roadblock for companies looking to deploy Web services. As great as all of the discoverability and interoperability benefits of Web services sound, don t forget that Web services transmit data, potentially sensitive data, through the wild unknown of the Internet. While SOAP messages excel at providing a standardized interface for remotely accessing Web services, they do present an additional vulnerability when opening communication to them over the Internet. While even traditional binary communication protocols must be secured across the Internet, since SOAP messages are transmitted as a stream of human-readable XML, reading or tampering with an intercepted message becomes that much easier. Because of this, it s even more important to design security into your Web service. Sometimes even non- malicious users can cause problems for an unsecured Web service. For instance, if you provide a useful service such as a stock ticker or a sports reporting service to anyone sending a properly formatted SOAP request, don t be surprised when some enterprising developer has created an application that uses your service. If this application is poorly written (frequent requests and improper use of caching, for instance) or when the application becomes widely distributed, you ll see unanticipated and unexplained decreases in the performance of your service.
Although Web services are based on open standards and designed to be discoverable, this doesn t mean that they should be accessible to unauthorized clients . The requirements of some Web service applications mandate access control to its services.
Web services need to be designed from the ground up to use the best available security features and best practices, not just whatever is easiest to bring the service online. In developing effective and robust security for Web services, it s important to understand and plan for the types of attacks that might be launched against your service. In order to adequately secure a Web service, the following areas must be addressed:
Authentication It is important to verify who is making a Web service request. Unless you don t care who is accessing your service, requests that cannot be positively authenticated should be denied authorization and access to any resources. You also need to guard against malicious users impersonating, or spoofing, other users to gain access to your service.
Authorization If an authenticated party making the request does not have permission to access the service and any requested resources, then the request should be denied. Again, care must be taken in preventing malicious users from spoofing of an authorized user .
Secure messaging Data must be secure from malicious tampering as it travels across the Internet, the integrity of the message must be maintained , and the request itself could be encrypted for confidentiality.
Secure data access Web services should implement well-defined data access strategies and not allow ad hoc access to underlying data sources.
Denial of service Even when everything else has been done right, an attacker can attempt to block access to your service with a barrage of bogus requests.
Now let s take an in-depth look at techniques to secure these vulnerable areas of your Web service.
Authentication is the process by which a party presents information to a second party to prove its identity. In order to establish the trust needed to communicate securely, both parties should complete this process, known as mutual authentication. In the context of our discussion, this process involves an application accessing the resources of a Web service. During mutual authentication, an application makes a request that includes one or more claims about its identity along with information sufficient to prove this identity to the Web service. An example of a simple claim is I am Bob, where this claim can be included in the request message header as < username >Bob< /username >. In this case, Bob is known as the principal. Of course, our principal, Bob, still needs to prove that he actually is Bob and not just Nancy or Tim claiming to be Bob.
To prove to the service that he is who he claims to be, Bob proves that he has a piece of information that both he and the service know. This information, known as proof-of-possession, can be a shared secret, like a password or a randomly generated cryptographic key, or it can be a cryptographic endorsement issued by a trusted third-party service. When the proof-of-possession is a shared secret, the secret itself should never be sent with the message unless the message is first encrypted; otherwise , the secret is at risk of interception, which can lead to a spoofing attack. A more secure way to demonstrate proof of possession is to use the shared secret to cryptographically generate a separate proof-of-possession that is bound to the message itself. In such situations, this digital signature, generated using the shared secret and the message itself, can be sufficient to prove possession and back up the original claim. I will discuss digital signatures in more detail shortly.
After receiving the message, the Web service verifies that the proof-of-possession matches the authentication claim being made, which in the case of a digital signature means that the signature generated using the recipient s copy of the shared secret matches the one included in the request message. Once this verification is made, the requestor is considered authenticated. This combination of a claim and its related proof-of-possession is also referred to as credentials. Often, during the initial authentication, a principle will be assigned a temporary shared secret key to use in subsequent requests to the service. This solution, used in many authentication mechanisms “ including Microsoft Windows, eliminates the need to directly use passwords as proof of possession. This also is the basis of the WS-SecureConversation specification that I will discuss in Chapter 8.
The WS-Security specification introduces the concept of security tokens, which are representations of authentication credentials, and it differentiates between signed and unsigned security tokens. A username and password is an example of an unsigned security token, where the recipient must be able to verify the token with its own copy of the username and password before trusting the sender. Signed security tokens are created by a security authority and are cryptographically signed, or endorsed, by this authority s own proof-of-possession. Some well-known examples of signed security tokens are Kerberos tickets and X.509 certificates, which I will discuss shortly. When accepting a signed security token, if a Web service trusts the authority that created the token, then it can authenticate the requestor based on that trust. In Chapter 8, I will go into more detail on trust relationships, security token services, and how temporary security tokens are created. Because WS-Security is extensible, it also supports XML-based security tokens and authentication mechanisms, like the Security Assertion Markup Language (SAML) and the eXtensible rights Markup Language (XrML); however, I do not discuss these mechanisms in this book.
Most authentication methods require that both parties have copies of proof-of- possession information, whether passwords, hashed passwords, or shared secret keys. Because both parties possess a copy of the secret key, this is known as symmetric key authentication. The drawbacks to such methods are related to management of the shared secret keys, distributing them, and keeping them safe, especially on public networks like the Internet. Asymmetric authentication mechanisms were designed to solve some of these key management challenges in public networks by using key pairs instead of shared secret keys.
In this type of authentication, each party has a private key, which is used to sign the message, thereby demonstrating proof-of-possession, and a corresponding public key, which can be freely distributed, that is used to verify the signature. The public key is generated by a cryptographically irreversible operation on the private key so that the private key cannot be determined from the public key. The other cool behavior of public/private key pairs is that a sender can encrypt the contents of a message with the recipient s public key, and on receipt, the private key can then be used to decrypt the message. Asymmetric key-based authentication is the basis for this Public Key Infrastructure (PKI) that is used by the X.509 security standard. Since asymmetric algorithms are less efficient than symmetric ones, asymmetric keys are often used to safely transport a temporary symmetric key that is only valid for the duration of the exchange. Figure 5-1 illustrates how PKI can be used to securely transport sensitive data between Bob and Tom, assuming that both Bob and Tom have access to, and trust, each other s public keys. This sensitive data might be a shared symmetric key that can be used to encrypt the rest of the conversation.
In the X.509 security standard, public keys, endorsements made by a Certificate Authority (CA), and additional metadata comprise an X.509 certificate. WS-Security defines a special signed security token type for binary security tokens that contain an X.509 certificate, which is encoded so that it can be transported in a SOAP message. Certificates are distributed by a Certificate Authority (CA). When an X.509 certificate is issued by the CA to a trusted principal, it contain a public key, and depending on the protocol used, the related private key may also be sent.
When making a request to a Web service, a token representing a certificate, which contains a copy of the sender s public key, is sent to the service. In addition, the request message is signed with the sender s private key and optionally encrypted with the recipient s public key. When received, the Web service can use its private key to decrypt the message and use the attached token to verify the sender s signature, which demonstrates proof of possession. Later in this chapter, I will show how WSE implements X.509-based security.
Kerberos was originally designed by researchers at the Massachusetts Institute of Technology (MIT) to better enable the execution of security permissions on distributed networks and through secure firewalls. A foundation for security authentication in Windows 2000, Windows XP, and Windows Server 2003, Kerberos is a distributed security protocol that provides a way for entities such as users and services or clients and servers to authenticate themselves to each other. Kerberos, also spelled Cerberus, was the three-headed dog in ancient Greek and Roman mythology that was believed to guard the passage to the underworld. This name is appropriate because the protocol involves the interaction of two principals (the user and the service) plus a third party that issues signed security tokens.
In a Web services scenario, Kerberos provides a method for a third-party service to independently verify trust with two parties and then to securely distribute shared secret keys that these two parties can use as the basis of a secure interaction. In this scenario, a principal s credentials are maintained by a third- party key distribution center (KDC). The KDC has two functions: it acts as both the Authentication Service (AS), whose job is to authenticate users based on their supplied credentials (typically username and password), and the ticket- granting service (TGS), whose job is distributing service access tickets that contain the shared secret key. The Kerberos process for a client accessing a Web service includes the following steps, as shown in Figure 5-2:
The client sends an authentication request to the AS portion of the KDC.
The AS sends a challenge message back to the client.
The client uses a persisted master key to sign the response, where the KDC has a copy of this master key.
After verifying the signed response, the AS returns a ticket-granting ticket (TGT) containing a temporary secret key that can be persisted during the session to prevent having to use the permanent credentials.
The client presents the TGT to the TGS portion of the KDC in a request to access the desired Web service.
The TGS returns a service ticket to the client containing a temporary session key that will be shared with the Web service. The service ticket contains two encrypted copies of the session key, one for the client and one for the Web service. Each copy of the session key is encrypted with the appropriate party's master key.
The client decrypts the service ticket and uses its copy of the key in the session ticket to secure the message to the Web service.
The client sends a request message to the Web service along with the service ticket.
The Web service uses its persisted credentials to decrypt its copy of the session key from the session ticket.
The Web service uses the session key to access the contents of the message.
Figure 5-2: Kerberos KDC distributing tickets to enable service access.
The strengths of the Kerberos protocol lie in the fact that the parties involved in an interaction never need to exchange or possess the other s credentials because the KDC shares a secret with each of the principals. Like X.509 certificates, WS-Security defines special signed security token types for binary security tokens that represent either a Kerberos service ticket (ST) or a Kerberos ticket-granting ticket (TGT), which enables you to use Kerberos authentication for your Web service. Also, version 2.0 of WSE provides support for Kerberos- based tokens.
While authentication is concerned with proving identity and verifying trust, authorization is concerned with determining if a principle has permission to access Web service resources. For example, just because Bob can prove that he is in fact Bob, it doesn t mean that he has the privileges to access the method on a Web service that he s requesting. Often applications will make authorization decisions based on information provided by the requester. If Bob sends a request to a Web service that includes his user information, the service can check internally to see whether it should fulfill Bob s request.
The process of authorization is always separate from the authentication process. Sometimes, however, the same service can make both authorization and authentication determinations, as is possible with Kerberos. Since it can be considered risky to have authorization information distributed across many servers, it makes sense also to keep a central authorization server that can be hardened like an authentication server ”even user identifiers can be of value, even without the corresponding password information. In Kerberos, when Bob presents his TGT to the KDC with a service request, an authorization decision is actually being made as to whether Bob can access the service. Only after Bob has been authorized by the KDC will he be granted the service ticket that allows him to access the service. Regardless of what type of security token is presented for authentication, WSE provides a built-in mechanism for authorizing Web service access to a given principle, which we will see later in this chapter.
As a general rule, all of your applications should adhere to the principle of least privilege. This principle dictates that any application should only be given the access permissions needed to do the specific task of the application. This means that if the application does not need to write to a disk, then it should not be granted write permissions to that disk. Also, the user account under which the application runs, which for a .NET Web service is a special ASP.NET account, should never be an administrator account or a member of a group with high-level privileges. The application should only be granted the lowest levels of privileges needed to get the job done.
For years , transport-level encryption has been the magic bullet of Internet security standards. The two main protocols that are used to implement transport- level security are IP Security (IPSec), which implements security at the Internet Protocol (IP) level, and Transport Layer Security (TLS), more commonly referred to as Secure Sockets Layer (SSL). The IPSec provisions for authentication, integrity, and confidentiality over the IP protocol has already been leveraged to provide such benefits as secure virtual private networks (VPNs), which many corporations use to provide intranet access to remote workers.
Developed by Netscape, the SSL protocol is a client/server protocol between the lower-level transports of TCP/IP and the higher-level HTTP protocol that allows an SSL server to authenticate itself to an SSL-enabled client in order to undertake encrypted communication. The SSL protocol has played a major role in the successes in e-commerce in recent years by making Internet connections secure enough to allow credit card transactions. For a technical discussion of SSL, see the SSL specification at http://wp.netscape.com/eng/ssl3 .
SSL can be used in a Web service architecture because any SOAP message can be sent fully encrypted over the wire via SSL. However, as beneficial as SSL has become, as usual there are trade-offs between security, functionality, code complexity, and performance. For example, securing any transaction using an encrypted transport will be slower than without such confidentiality measures because of the high cost of encrypting and decrypting data. Also, since SSL establishes a secure dialogue between a client and a server at the transport level, messages sent via SSL must be sent direct, which means you can t take advantage of many of the routing functionalities supported by SOAP without revealing the unencrypted message to each intermediary.
WS-Security proposes a more precise method for securing SOAP messages. If a SOAP message must be routed or forwarded to other recipients, transport- layer encryption cannot be used to maintain security throughout the entire message path . An encrypted transport, like SSL, can only be used between individual message endpoints because, among other limitations, such encryption prevents intermediate SOAP routers or Web services from reading SOAP headers to determine where the message should be sent next without incurring all of the decryption and re-encryption costs just to check the message headers. WS-Security leverages the security features detailed in the XML Encryption and XML Signature standards to secure only the necessary parts of the SOAP message. As I will discuss shortly, a signature can be generated over all or part of a message, and this signature can be validated by the recipient against its own signature of the message. If the signatures do not match, then the message has been changed and should be considered invalid. Likewise, all or part of the SOAP body as well as part of the header can be encrypted using a shared secret key or a public key in the case of PKI. In this way, only a holder of the corresponding shared key or of the private PKI key can decrypt and interpret the message. When attaching a username token to a SOAP message, as prescribed by WS-Security, an encrypted transport should still be used to maximize security.
While secure data access does not relate specifically with Web services or WSE, I feel that this discussion is important when outlining end-to-end security for Web services. This is because even after implementing security in all of the previous areas, you should still plan for a secure interaction between the Web service application and its underlying data store. Otherwise, should an attacker manage to successfully impersonate, or spoof, an authorized user of your Web service, they could access or even damage data used by the Web service. For example, if your Web service has a method that allows client applications to submit ad hoc queries that are then executed against a database or stored XML document and if an attacker manages to spoof a valid user, then being able to submit any query string essentially gives them unrestricted access to all of the data in your data source. If you want to keep your data secure, do not allow clients to supply their own query strings. You should also not build query strings for data access directly from data supplied by the client, since a malicious client can supply strings that when concatenated into a query can lead to elevation of privileges or even destruction of data.
While an application should always validate any externally supplied data, the most secure method for data access is to create pre-defined stored procedures or data access functions. In this way, any user inputs can be restricted to the expected data types and can be validated within the stored procedure or function. When your data source is SQL Server or any other database that supports stored procedures, using stored procedures and validating any string inputs is by far the best way to prevent so-called SQL injection attacks. You should also apply the least privilege principle for data access by restricting access from your ASP.NET account to only the database objects needed to complete the defined application tasks . That way, the database will block access to unrelated data during a successful spoofing attack.
One of the biggest vulnerabilities of Web services, even those with good authentication and authorization schemes, is the denial of service (DoS) attack. A DoS attack is launched by generating a barrage of valid SOAP requests with the sole purpose of making the service unavailable by consuming resources (network, memory, and CPU) needed by the service as it tries to handle all of the requests. When multiple computers are involved in a coordinated attack, it is known as a distributed denial of service attack (DDoS). Even if the attackers cannot be authenticated, the SOAP request must still be handled and a response must be generated. The best way to head off the barrage of malicious requests that comprise a DoS or DDoS attack is to apply custom logic, such as ISAPI filters, to intercept malicious packets at the Web server. Another emerging solution to this type of attack is to use XML filters to validate and inspect the contents of SOAP requests at the firewall. The WSE does what it can to help mitigate the effectiveness of DoS attacks. Since the key to handling such attacks is to fail invalid requests as quickly as possible, the security input filter is one of the first input filters that parses an incoming SOAP message as it passes through the WSE filter pipeline. This enables request messages without valid credentials to be rejected without any more processing being done by the WSE or your Web service application.