2

I am trying to validate a JWT token received from Windows Azure. I am following the documentation here: https://azure.microsoft.com/en-us/documentation/articles/active-directory-v2-tokens/#validating-tokens

When you request a token Azure makes you supply a nonce, and the returned JWT token contains the nonce you sent, and you are supposed to make sure they match. A common problem in this situation is that the server is stateless and there may be multiple servers, so it is not easy to store the nonce for comparing to the value in the token when the token is received.

Here's what I am planning to do: When I redirect the browser to https://login.microsoftonline.com/ I will store the nonce in a cookie. When the token is received from Azure, and the browser sends the token to my server I will also get the nonce in the cookie and I can compare them to make sure they match.

This is an easy solution to the problem of where to store the nonce. But the question is, is this strategy consistent with how nonce is supposed to be used? Since the nonce is being transferred to/from the client, does that break the protection offered by nonce? Will this enable replay attacks and render the nonce worthless? To answer these questions I need to know what sort of attacks I am trying to prevent.

So the question is, what are some examples of replay attack scenarios the nonce is designed to prevent? Is the attacker somewhere on the Internet, in which case SSL can be used to prevent him from seeing any communication? Or is the attacker on the same computer as the user, i.e., after the user leaves the computer, the attacker uses the computer and the browser which the user neglected to close?

How exactly does a replay attack work?

1

As per OpenID Connect Core documentation:

The nonce parameter value needs to include per-session state and be unguessable to attackers. One method to achieve this for Web Server Clients is to store a cryptographically random value as an HttpOnly session cookie and use a cryptographic hash of the value as the nonce parameter. In that case, the nonce in the returned ID Token is compared to the hash of the session cookie to detect ID Token replay by third parties. A related method applicable to JavaScript Clients is to store the cryptographically random value in HTML5 local storage and use a cryptographic hash of this value.

So yes it is acceptable to store it in a cookie, but it is recommended to use a secure hash such as SHA-2 when this value is sent to the authorisation server from the user's browser.

This protects against a stolen token, because the attacker that has stolen the token will not have this session cookie on your site, and is unable to guess or reconstruct it because the value is hashed when sent externally.

The attacker would be on the internet, because if the user is local all bets are off - they would be able to access the token sent to your application, and would be able to access this session cookie.

So what is it protecting against?

Remember that if you are relying on OpenID to authenticate your users, you are trusting a third party. In an ideal world, the security of the provider is absolute and nobody can intercept the token. However, if there's a weakness in the chain between the user and the OpenID Provider, for example there's an unreported token leakage vulnerability there allowing an attacker to observe the token, the nonce will ensure that they cannot login to your application by replaying the redirect to your site.

The value of a nonce over simply validating they have any session on your site is that it pairs their original access to your site when you redirected to the provider, with the return to your site.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.