Recently, I’ve been helping a customer with some Web Service issues. One of the problems was their limited knowledge of security in that area. He asked me to explain, in Jip and Janneke language [1] how SSL works and what it actually secures.

There seems to be a lot of misunderstanding about Web Service security. Using password authentication doesn’t prevent unauthorized users to access your services, while SSL / HTTPS doesn’t give you any information about who is trying to access your services. And did you ever think of signing you messages with a digital signature?

In my introductory post I’ve elaborated on what type of security we’d typically want on Web Services.

This article will go more in-depth in the Username Token authentication.

First, I’ll list the 5 security requirements we usually have to feel really secured. These have been treated in the introductory post in this series.

  1. The client must be sure it sends it messages to the correct provider;
  2. The provider wants to be sure that the client is authorized to;
  3. The provider wants to be sure that the client is who it says it is;
  4. Both the consumer and provider want to be sure that the messages can only be interpreted by eachother;
  5. Both parties want to be sure that the message sent is received unchanged.

The username token will take care of items 2 and 3. The username token is typically a security header in the soap message from the client towards the server. This header contains a username and a password, in one form or another.

In the simplest form, a UsernameToken authentication header contains an element with a username and one with a password. This is the “PasswordText” option of the UsernameToken. When you send this message unencrypted, anyone would be able to read your username and password, an log in on your behalf. Encrypting the communication will solve this risk. However, if the message has to pass several endpoints and one of the connections in unencrypted, your password is open again, despite effort to secure it.

To prevent giving away the username and password combination for free, it is possible to use the “PasswordDigest” version of the UsernameToken. This will actually pass a hash of your password, instead of the password itself. This prevents malicious ears from plucking you password off the wire.

However, although the password is encrypted and unknown to any third party, that third party could log log in by copying the entire security header. After all, if one client can get in using that header, any client could. To prevent this, a Nonce and/or a Timestamp are made part of the hash too. The Nonce is a random value, chosen by the client. The Timestamp is the date and time the password was hashed.

So how does this prevent another user from replicating your authentication header? Well, if a Timestamp is used, the server could require that that timestamp may not be older than for example 5 minutes. This still gives the third party a 5 minute window to abuse your password. That’s where the Nonce comes in. The server can (and should) require that the Nonce may be used at most one time. If the same header -and thus the same nonce- is sent again, the UsernameToken is refused based on a duplicate nonce.

In the end, the security header could look like this:

<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” SOAP-ENV:mustUnderstand=”1″> <wsse:UsernameToken xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd” wsu:Id=”UsernameToken-33083972″ xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”> <wsse:Username xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>username</wsse:username> <wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest” xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>Zb5nkZdaXM3hH/bVPQRdMdYSbdo=</wsse:password> <wsse:Nonce xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd”>hHDHOSh3akTwwZFs+6o13A==</wsse:nonce> <wsu:Created xmlns:wsu=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd”>2008-05-20T19:00:06.937Z</wsu:created> </wsse:UsernameToken> </wsse:Security>

So, does this make us absolutely secured from any attacks? Well, the likelyhood of anyone abusing your security header is very slim, but nowhere near to zero. Hackers keep lists of commonly used passwords and can use these lists to guess your password. They will see which passwords will create the given hash using the Nonce and Timestamp you have provided. It is therefore very important to generate a password instead of choosing one which is easy to remember. Why would you anyway, a client is usually a piece of software that doesn’t really have difficulties remembering any password. It is of course still not water tight, but it is more likely that the service won’t exist anymore by the time the password has been guessed.

Another way to minimize the chance of abuse of your credentials is by encrypting the messages, or parts of it. This shall be treated in my next post in this series.

The configuration of UsernameToken security in your WebService is fairly simple. Both in client and server only little configuration is needed. There are libraries that can assist you in setting up security, such as Apache’s WSS4J and Sun’s XWSS. If you want to see these libraries at work, make sure you download the code samples for this series on the Gridshore code repository: http://code.google.com/p/gridshore/source/checkout [1].

If you want to go into a little (or a lot) more technical depth of the UsernameToken specification, make sure you read the OASIS WSS specification from http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss#technical.

This concludes this post about the UsernameToken. In my next post in this series, I will shed some light on Transport Level Security and Message Encryption.


[1] Make sure you checkout the code in the /trunk/feeling-secure-with-webservices/ folder. If you check out the entire trunk, you’ll have to deal with lots of samples.

Feeling secure with Web Services – Part 1 – The UsernameToken
Tagged on:                 

4 thoughts on “Feeling secure with Web Services – Part 1 – The UsernameToken

  • July 12, 2008 at 12:37 pm
    Permalink

    Hi Ken,

    dit you read part 2? In that article I refer to our code repository where there is actually an example where signing and encryption are used together.

    When a message has to be both signed and encrypted, it doesn’t really matter in what order you apply them. However, if you only want to sign part of what you want to encrypt, you’ll have to sign first, as there is no notion of elements anymore after you’ve ecnrypted data (it’s just an unreadable blob of data).

    In Spring-WS, you’ll have to specify two different interceptor beans (same class thoug), since both need a diiferent key from your keystore. The example code shows an example of this.

    Good luck

  • July 11, 2008 at 9:27 pm
    Permalink

    Hello

    What I meant about Signing-then-Encrypting-then-Signing is how to use Signature and Encryption together for a XML file.

    Regards

  • July 7, 2008 at 8:42 pm
    Permalink

    Hi Ken,

    I partly agree with you if you say WSS is complicated. There is pretty good support for WSS in web service stacks (see our example project on google code). So something is already done about it. What is left is pretty hard to make easier.

    We don’t have an open source project. On this blog we just express our opinions and (sometimes) support that with sample code.

    About your first question, I don’t really understand what you mean. Signing and Encrpytion are two very distinct technologies that achieve different goals. It is never a choice of one or the other. It’s whatever you need to happen.

  • July 7, 2008 at 1:21 am
    Permalink

    Hello Allard Buijze,

    Thanks for your post.

    I’m also interested in WebService Security, and have some experience with both Transport Level Security and Message Level Security. I hope we could discuss more to make WSS useful and widely recognized in the industry.

    I have three questions
    1. Did you come up with a good scheme either to Sign, Encrypt and Sign, or Encrypt, Sign and Encrypt ?
    2. While WSS is supported by Big Guys of the IT world, it is still too much complicated, can we do something about it ?
    3. Does your gridshore.nl group have some open source project that I can join ?

    I thank you for your time

Comments are closed.