WS-Security is a specification that unifies multiple Web services security technologies and models in an effort to support interoperability between systems in a language- and platform-independent manner. More specifically, WS-Security specifies a set of SOAP extensions that can be used to implement message integrity and confidentiality. To this end, the WS-Security specification brings together a number of XML security technologies and positions them within the context of SOAP messages.
The origins of WS-Security are with Microsoft, IBM, and VeriSign submitting a group of security specifications to the Organization for the Advancement of Structured Information Standards (OASIS). Later, Sun Microsystems started to cooperate to further develop the specifications. With such heavyweights behind it, WS-Security is emerging as the de facto standard for Web services security.
WS-Security is a unified model and specification for message protection within a Web services environment. WS-Security specifies standardized means by which the header, body, attachments, or parts of a message can be protected through a combination of encryption and digital signatures.
As we discussed earlier in this chapter, the W3C has developed specifications for XML Encryption and XML Digital Signatures. WS-Security provides message integrity, authentication, and non-repudiation by using security tokens and the W3C's XML Digital Signatures specification. WS-Security provides message confidentiality by using security tokens and the W3C's XML Encryption specification. Essentially, WS-Security builds on these key XML technologies and specifies elements that support these technologies within the context of SOAP messages.
In particular, WS-Security specifies XML structures (within the context of SOAP messages) for security claims and tokens. Security claims are statements that a client (or a user) makes. Claims can include the client's name, identity, key, rights, and privileges. A security token is a collection of security claims. A password and a digital certificate are examples of security tokens.
Security claims can be either endorsed or unendorsed by a trusted third-party. Claims are generally of the following three types:
WS-Security provides a flexible and extensible means by which the sender of a message can make security claims by associating security tokens with a SOAP message. Based on the WS-Security specification, Web services should ignore messages with invalid or inappropriate security claims.
In the remainder of this section, we describe the major XML structures of the WS-Security specification and how they are used within SOAP messages. More information about the WS-Security specifications can be found at http://www.verisign.com/wss/wss.pdf.
The Security Header Element
Each SOAP message has a receiver that receives the incoming SOAP message and acts on it. In the WS-Security specification, this receiver is called an actor. The Security header element provides information for the receiver of the SOAP message and specifies the actor.
A message may have one or more actors. For example, consider a Web service transaction to purchase a book. The bank must parse the payment information, such as the credit card number, where the bookstore must parse the book title and quantity information. In this case, there are two actors the bank and the bookstore. The use of multiple actors for security purposes within a single SOAP message is depicted in Figure 8-9.
Figure 8-9. Multiple Security header elements used within a SOAP message.
<soap:header> <Security actor = "bank.example.org"> . . . </Security> <Security actor = "bookstore.example.org"> . . . </Security> </soap:header>
Security information for different actors must appear in different Security elements. For instance, encryption and signature information for each actor must appear within a Security element.
If the actor is unspecified within a security element, any receiver can use that information. However, since multiple receivers may use the information contained within the security element, the element cannot be deleted until the message reaches its final destination. A Security header element without a specified actor attribute can only appear once within a message, and two Security header elements cannot specify the same actor.
After a receiver processes a message, the Security header for that actor can be deleted before the message is forwarded to its next destination. However, if a subelement within a Security element is referenced by a subelement within another Security element and a receiver deletes the original security element, the receiver must prepend the referenced information.
The UsernameToken Element
The UsernameToken element simply provides a means to associate basic authentication information such as a username and an optional password with a message. Figure 8-10 illustrates the use of this element.
Figure 8-10. The UsernameToken element syntax.
<UsernameToken > <Username>...</Username> <Password Type="...">...</Password> <Nonce EncodingType="...">...</Nonce> <Created>...</ Created> </UsernameToken>
The Id attribute of the UsernameToken element is a string label for identifying this security token. The Username subelement specifies the client's username, while the optional Password subelement specifies the password. The optional attribute Type of the Password subelement specifies the type of the password. The pre-defined password types are PasswordText and PasswordDigest. PasswordText, which is the default if no type attribute is specified, indicates that the actual password is given as the value of the Password element, while the PasswordDigest type indicates that the digest of the actual password is given as the value of the Password element.
The optional elements Nonce and Created were added to the specification as extensions for use in those cases where an increased level of protection is necessary and both the sender and the receiver know the plain text password. The optional attribute EncodingType of the Nonce element specifies the encoding type of the nonce, with a default encoding of Base64.
In the case where either the Nonce or the Created elements are used, a PasswordDigest can be calculated and transmitted as follows:
Password_Digest_Value = SHA1 ( nonce + created + password )
The value of the digested password is calculated on the concatenation of the nonce (if present), the created timestamp (if present), and the actual password. This approach provides a means to obscure the actual password as well as to help prevent replay attacks.
The BinarySecurityToken Element
Binary or other non-XML format security tokens are specified with the BinarySecurityToken element. Examples of binary security tokens include X.509 certificates and Kerberos tickets. Figure 8-11 illustrates the use of this element.
Figure 8-11. The BinarySecurityToken element syntax.
<BinarySecurityToken ValueType="..." EncodingType="..."> ... </BinarySecurityToken>
The Id attribute of the BinarySecurityToken element is a string label for identifying this security token. The ValueType attribute specifies the value type and value space of the security token. The pre-defined values for ValueType include X509v3 for a X.509 v3 certificate, Kerberosv5TGT for a Kerberos v5 ticket granting ticket, and Kerberosv5ST for a Kerberos v5 service ticket. The EncodingType attribute specifies the encoding format of the binary data of the security token. The pre-defined values for EncodingType include Base64Binary for base-64 encoding and HexBinary for hex encoding.
The SecurityTokenReference Element
The SecurityTokenReference element provides a means to reference a security token instead of the token itself. The security token is accessed and "pulled" by the receiver from a specified URI. Figure 8-12 illustrates the use of this element.
Figure 8-12. The SecurityTokenReference element syntax.
<SecurityTokenReference > <Reference URI="..."/> </SecurityTokenReference>
The Id attribute of the SecurityTokenReference element is a string label for identifying this security token. The URI attribute of the Reference element specifies the location of the security token.
The SecurityTokenReference element is also commonly used as a child element of the KeyInfo element (see next subsection) to specify the location of a security token containing the key information used for the signature or encryption steps.
The KeyInfo Element
The KeyInfo element is used in a similar manner as the BinarySecurityToken element, but is used for different types of keys and is specified for future extensibility. For well-defined key types, BinarySecurityToken is the preferred element to use.
Figure 8-13. The KeyInfo Element usage syntax.
<KeyInfo <KeyName>...</KeyName> </KeyInfo>
The ID attribute of the KeyInfo element is a string label that specifies the identifier for this key.
The Signature Element
The Signature element is used to add a signature that is compliant with the XML Digital Signatures specification for signing one or more elements of the SOAP Envelope or its attachments. Each SOAP message can carry multiple signatures, each of which may reference different or overlapping parts of the message.
Although WS-Security builds on the XML Digital Signatures specification, signatures within a SOAP envelope should not use the Enveloped Signature Transform or the Enveloping Signature of the XML Digital Signatures specification. This is because SOAP headers can legitimately change as SOAP messages are processed by multiple servers en route to their final destination. Instead, each of the signed elements should be explicitly identified.
The extended example at the end of this section illustrates the use of digital signatures within a SOAP message as specified by the WS-Security specification.
The ReferenceList Element
The first of three elements that are defined within the XML Encryption specification and can be used within a Security header element for encrypting parts of a SOAP envelope is the ReferenceList element. The ReferenceList element is essentially used as a manifest of the encrypted portions of the message.
Figure 8-14 illustrates the usage of the ReferenceList element within a SOAP message.
Figure 8-14. The ReferenceList Element used within a SOAP message.
<S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/ 04/secext" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header> <wsse:Security> <xenc:ReferenceList> <xenc:DataReference URI="#encryptedPartID"/> </xenc:ReferenceList> </wsse:Security> </S:Header> <S:Body> <xenc:EncryptedData > <ds:KeyInfo> <ds:KeyName>...</ds:KeyName> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>...</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </S:Body> </S:Envelope>
The ReferenceList element is useful and typically used in situations where the sender and receiver of the SOAP message use a shared key.
The EncryptedKey Element
The EncryptedKey element is useful in situations where encryption is done using a key. This key is, in turn, encrypted using the recipient's key and the encrypted key is embedded within the message. All of the data that is encrypted using the original key must be enumerated within a ReferenceList element.
Figure 8-15 illustrates the usage of the EncryptedKey element within a SOAP message.
Figure 8-15. The EncryptedKey element used within a SOAP message.
<S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/ 04/secext" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header> <wsse:Security> <xenc:EncryptedKey> <xenc:EncryptionMethod Algorithm="..."/> <ds:KeyInfo> <ds:KeyName>...</ds:KeyName> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>... </xenc:CipherValue> </xenc:CipherData <xenc:ReferenceList> <xenc:DataReference URI="#encryptedPartID"/> </xenc:ReferenceList> </xenc:EncryptedKey> </wsse:Security> </S:Header> <S:Body> <xenc:EncryptedData > <xenc:CipherData> <xenc:CipherValue>...</xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </S:Body> </S:Envelope>
It is important to note that the only difference between Figure 8-14 and Figure 8-15 is in the Header contents. The contents of the Body of both messages are identical.
The EncryptedKey element is typically used when the sender of a message creates a randomly-generated symmetric key for encryption. The sender them encrypts the randomly-generated key using the recipient's key to securely communicate the original encryption key.
The EncryptedData Element
The EncryptedData element is most useful in situations where non-XML attachments are encrypted as well as in those cases where security information must be provided in a fully encrypted format. For each encrypted attachment, an EncryptedData element is added to the Security header element and the contents of the attachment are replaced with the encrypted octet string (MIME media type application/octet-stream).
If MIME types are used, the original media type of the attachment is declared within the MimeType attribute of the EncryptedData element. Moreover, the encrypted MIME part is referenced by a CipherReference element (as defined in the XML Encryption specification). The value of the URI attribute of the CipherReference element points to the MIME type prepended by the cid: scheme.
Figure 8-16 illustrates the usage of the EncryptedData element within a SOAP message in the communication of an encrypted JPG image attachment.
Figure 8-16. The EncryptedData Element used within a SOAP message to communicate an encrypted JPG image attachment.
<S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/ 04/secext" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header> <wsse:Security> <xenc:EncryptedData MimeType="image/jpg"> <xenc:EncryptionMethod Algorithm="..."/> <ds:KeyInfo> <ds:KeyName>...</ds:KeyName> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherReference URI="cid:image"/> </xenc:CipherData> </xenc:EncryptedData> </wsse:Security> </S:Header> <S:Body> </S:Body> </S:Envelope>
Since the function of the SOAP message in Figure 8-16 is simply to transmit the image attachment, the message Body is empty. The Body element tags are kept to maintain the validity of the SOAP envelope.
Putting It All Together
In this section, we analyze an entire SOAP message and illustrate the use of security tokens, signatures, and encryption as defined by the WS-Security specification. The entirety of the SOAP message envelope, including the header and the body, follows together with brief explanations of the key sections.
<?xml version="1.0" encoding="utf-8"?> This is the start of the SOAP envelope, and defines the various namespaces that are referenced within the envelope. <S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/ 04/secext" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header>
Following the envelope header, the routing information for this SOAP message specified according to the rules of the WS-Routing specification is enumerated. WS-Security and SOAP in general provide mechanisms to indicate that different parts of a message are for different receivers. WS-Routing provides a means by which to specify the actual routing of a message through a number of receivers. For instance, a SOAP message to purchase a book will first need to travel to the credit card processing Web service of a bank before it can be forwarded to the bookstore for order fulfillment. More information on WS-Routing can be found at http://msdn.microsoft.com/ws/2001/10/Routing/. These header elements are only included for completeness and are not critical to our discussions here on WS-Security.
<m:path xmlns:m="http://schemas.xmlsoap.org/rp/"> ... </m:path> <wsse:Security>
This is the start of the WS-Security Security header element. The BinarySecurityToken element is used to specify an X.509 v3 certificate security token with the identifier CertToken. The EncodingType attribute specifies the encoding as base 64.
<wsse:BinarySecurityToken ValueType="wsse:X509v3" EncodingType="wsse:Base64Binary"> ... </wsse:BinarySecurityToken>
The following specifies information about the key that is used to encrypt the body of this SOAP message. The actual symmetric key is encrypted and sent as part of the message. The Algorithm attribute of the EncryptionMethod element specifies the algorithm that is used to encrypt the key, while the KeyName subelement of the KeyInfo element specifies the key that is used to encrypt the original symmetric key. The value of the CipherValue element is the actual encrypted key, while the DataReference element specifies the part of the message body that is encrypted using the original symmetric key.
<xenc:EncryptedKey> <xenc:EncryptionMethod Algorithm="..."/> <ds:KeyInfo> <ds:KeyName> ... </ds:KeyName> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue> ... </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#encryptedBodyPart"/> </xenc:ReferenceList> </xenc:EncryptedKey>
The following specifies the digital signature for this SOAP message. First, the canonicalization and signature algorithms are specified. The contents of the Reference element identify the actual parts of the message that are being signed. The DigestMethod and DigestValue specify the algorithm for calculating the digest of the selected parts of the message and the resultant digest value, respectively. The SignatureValue element contains the actual signature, while the SecurityTokenReference subelement of the KeyInfo element indicate that the key used for the signature is the same one that was specified earlier in the message (with the reference identifier CertToken).
<ds:Signature> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="..." <ds:SignatureMethod Algorithm="..."/> <ds:Reference> <ds:Transforms> <ds:Transform Algorithm="..."/> ... </ds:Transforms> <ds:DigestMethod Algorithm="..."/> <ds:DigestValue> ... </ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue> ... </ds:SignatureValue> <ds:KeyInfo> <wsse:SecurityTokenReference> <wsse:Reference URI="#CertToken"/> </wsse:SecurityTokenReference> </ds:KeyInfo> </ds:Signature>
The following two lines indicate the end of the WS-Security Security header and the SOAP message envelope header, respectively:
The body of this SOAP message starts by specifying that an XML element value has been encrypted using XML Encryption and replaced with the encrypted data. The encryption algorithm is specified by the EncryptionMethod element, while the actual encrypted data is specified by the CipherValue element. The key that was actually used for the encryption was specified within the message header.
<S:Body> <xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" > <xenc:EncryptionMethod Algorithm="..."/> <xenc:CipherData> <xenc:CipherValue> ... </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </S:Body> </S:Envelope>
This SOAP message demonstrates how WS-Security provides mechanisms for data security, including encryption and digital signatures, within the SOAP envelope itself. This secured envelope can be transmitted using any transport protocol as it does not rely on any transport-level security mechanisms, such as SSL over HTTP.
Preventing Replay Attacks
Digitally signing and encrypting SOAP messages provides data protection, integrity, authentication, and non-repudiation. However, vulnerabilities may still exist. One such vulnerability is a replay attack in which a properly signed and encrypted message is repeatedly sent to a Web service. A replay attack is a special type of denial-of-service attack in which the Web service resources are so busy processing each of these repeated messages, that legitimate messages are denied access to the service.
Replay attacks may also have application-specific side effects. Consider a SOAP message that instructs a bookstore Web service to order a book and debit the purchase price from a particular bank account number. This legitimately encrypted and signed message can be saved by a malicious attacker and repeatedly sent to the bookstore Web service. This would have the application-specific side effect of ordering multiple copies of the book and depleting the user's bank account.
To address this serious issue, the WS-Security specification defines the Timestamp element for SOAP messages. The Timestamp element provides a means by which to indicate the creation and expiration times of a message, as well as the delays introduced by intermediaries along the message path. Using this information, the receiver of a SOAP message can make a determination as to whether to ignore or process an incoming message.
The Timestamp element supports the following three subelements: Expires, Created, and Received. The syntax for each of these subelements is as follows:
<Expires ValueType="..." >...</Expires>
The Expires element defines the expiration timestamp for the message. The value of the Expires element is in the UTC format as specified by the optional ValueType attribute. If the ValueType attribute is not specified, the default is assumed to be xsd:dateTime. The optional attribute Id can be used to reference this element.
The syntax for the Created element are as follows:
<Created ValueType="..." >...</ Created>
The Created element specifies the creation timestamp for this message. The semantics and default values for the optional attributes ValueType and Id are similar to those of the Expires element.
The syntax for the Received element are as follows:
<Received Actor="..." Delay="..." ValueType="..." > ... </Received>
The Received element specifies the time that an intermediary server received the message. The required attribute Actor specifies which actor received the message. Actor values must match those used within a WS-Routing header. The Delay attribute indicates the delay, in milliseconds, of the actor receiving the message. The optional attributes ValueType and Id are similar to those used by the Expires and Created elements.
Multiple Timestamp headers may be used within a message if they are for different actors. Both the Created and Expires subelements are optional but may appear at most once within a Timestamp element. The Received subelement is also optional, but may appear at most once per actor (unless the message path involves a loop).
It is interesting to note that the requestor's clock and the receiver's clock may not be synchronized. An assessment is necessary as to the level of skew to properly interpret the data specified by the Timestamp element. The WS-Security specification does not specify a means of synchronization, and any synchronizing mechanism, including an out-of-band, may be used.
Figure 8-17 illustrates the use of the Timestamp header element within a SOAP envelope to prevent replay attacks.
Figure 8-17. The use of the Timestamp element within a SOAP message to prevent replay attacks.
<S:Envelope xmlns:S="http://www.w3.org/2001/12/soap-envelope" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility"> <S:Header> <wsu:Timestamp> <wsu:Created>2003-08-15T06:27:00Z</wsu:Created> <wsu:Expires>2003-08-15T06:37:00Z</wsu:Expires> <wsu:Received Actor="http://bookstore.example.org/" Delay="60000"> 2003-08-15T06:30:00Z </wsu:Received> </wsu:Timestamp> ... </S:Header> <S:Body> ... </S:Body> </S:Envelope>
The Timestamp header element specifies a creation time of 6:27 on August 15, 2003, and an expiration duration of ten minutes. The intermediary bookstore.example.org specifies that it received the message three minutes after it was created and added a processing delay of one minute.
As we have seen, the WS-Security specification provides a rich set of XML structures to be used within the context of SOAP messages for security and related purposes. By providing security information in a standardized manner within SOAP messages themselves, message data security becomes transport-independent and more interoperable between multiple disparate systems.