Web Service Security UsernameToken Primer


Challenge


A subject that I still see a lot of misunderstanding around is how best to use the UsernameToken when using a user id and password as the basis of authentication for a Web service.


Recommendations



Background


The UsernameToken is based on a Web service security specification (http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0.pdf) which describes how a client can provide a Username which should uniquely identify a user and optionally a password or password equivalent that can support autheitcation. This specification includes a range of options some of which are in my opinion useful – and others that should be used with caution.


WSE 2.0 and 3.0 Implementation of UsernameToken


In the Microsoft Web Services Enhancements (WSE) implementation of UsernameToken, a password is used to establish proof–of-possession. The password sent in a UsernameToken message can be a cleartext password or a password equivalent, which is a unique representation of a password, typically created by hashing (and salting) the cleartext password,


Alternatively an XML signature created using the shared secret could be used as the basis of authentication – in which case the service would have to recreate the equivalent XML signature in order to ensure the same shared secret is possessed by both client and service. When a message is signed, the password used to sign the message is never included in the UsernameToken, because including it would compromise the signature.


After the message is received by the service, the AuthenticateToken method of the UsernameTokenManager class is used by WSE to validate the information in the UsernameToken. The AuthenticateToken method returns the password that was used for authentication. This return value is used by WSE to validate the original message. The specific type of validation is based on the password option that was used.


Note: AuthenticateToken can be overridden, allowing UsernameToken to be used in conjunction with custom identity providers. WSE 2.0 and 3.0 supports authenticating tokens based on a Windows user account with the password sent as plaintext (see options later in this document). In all other cases, a custom UsernameTokenManager is required.


WSE defines three password options used to send a password in the message: SendNone, SendPlainText, and SendHashed.


SendNone


This option may be used in two scenarios. The first is where the sender signs the message with an XML signature based on their password. The password is never sent in the SOAP message, The recipient then needs to use the same password in order to verify the sender’s signature. This is accomplished by returning the password used to sign the message from the AuthenticateToken in the UsernameToken manager. While I believe it would be possible to implement this in WSE 3.0 using API’s I believe WSE 3.0 has simpler and more secure approaches. (Keep reading)


The second scenario is where a UsernameToken is being used to flow identity across tiers in a TrustedSubsystem scenario. For a complete description of Trusted Subsystem pattern take a look at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/WSSP.asp, and for an example of this in practice take a look at our WS-I BSP Sample Application for an example of this – http://msdn.microsoft.com/practices/guidetype/RefImp/default.aspx?pull=/library/en-us/dnpag2/html/MSWSIBSP.asp.  .


SendPlainText


The password is always sent as plaintext in the SOAP message. This option is recommended only when the UsernameToken is encrypted using a security token or certificate obtained from the target Web service, or when a transport protocol such as SSL is used to connect to the Web service. Otherwise, the password could be intercepted and compromised. WSE running on the recipient's computer compares the password in the SOAP message to the one returned from the AuthenticateToken method. If the two values are identical, the password is deemed valid.


WSE 3.0 supports protecting the password using the two standard security assertions – usernameForCertificate and usernameOverTransport. For more information on how this works take a look at our Direct Authentication pattern (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/WSSP.asp) and Implementing Direct Authentication pattern (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/wss_ch3_impdirectauth_wse30.asp).


SendHashed


From what I have seen this is the option that causes the most confusion. It is important to remember that this option is only intended to provide security on the wire – between two endpoints. It will not help you ensure your password is stored in a database in a hashed format! This is critical – see recommendation number 1. For more information on how to do this using AD, SQL or ADAM see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/wss_ch3_impdirectauth_wse30.asp.


If you are interested in better understanding this option – read on. I would also suggest thinking carefully about using this option in lieu of encryption as for the most part people’s passwords are low entropy and lend themselves nicely to offline guessing attacks. Keith Brown talks a lot more about this in his white paper http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnwse/html/securusernametoken.asp.


The hash of the password is sent in the SOAP message. When a SOAP message is received with a UsernameToken, WSE calls the AuthenticateToken method of a custom UsernameTokenManager class, which is registered in the configuration file. The AuthenticateToken method returns a password or password equivalent, which WSE creates a hash from. That hash is compared to the hash in the SOAP message and if they are identical, the hashed password is deemed valid.


The formula used to calculate the hash is: P_SHA1 (password, label + nonce + created) where:


●    Password is either the real password or a password equivalent (for example, the hash of the real password) represented as a UTF-8 string.


●    Label is a shared string between sender and receiver, also a UTF-8 string. For the WSE 2.0 Tech Preview, this is the string "WS-Security".


●    Nonce is "Number Once" material, a random sequence of bytes generated from a cryptographic Random Number Generator (RNG), encoded as Base64.


●    Created is the created time for the token specified in Zulu T[tbm1] ime using xsd:DateTime format, again encoded as a UTF-8 string.


In addition to verifying the hash, WSE also signs the message with HMAC-SHA1 using 16 bytes of key data from the hash keys.

Comments (3)

  1. Avkash says:

    hi!!

    Actually i m working for development of "web services security assessment tool " and i need some help to understand "how one can perform bufferoverflow attack on any web service and how we can stop them???"

    i kindly request u 2 provide any help u can….

  2. Jason Hogg says:

    Hi Avkash, I am not sure if you would necessarily be performing a buffer overflow attack on a service, rather then platform on which the service is running. In terms of how you prevent buffer overflow attacks assuming you don’t own the platform, a good place to start would be to specify max message sizes on your incoming messages. Not entirely sure if I understood you – so hopefully this helps.

  3. Ross Mallett says:

    "In addition to verifying the hash, WSE also signs the message with HMAC-SHA1 using 16 bytes of key data from the hash keys."

    Could you elaborate on this? I’m trying to validate the HMAC-SHA1 SignatureValue from a WSE3 client and I cannot derive the same SignatureValue.

Skip to main content