The openid connect specification adds a nonce parameter to the authorize endpoint, which must be echoed back as a claim in the id_token. It claims that the purpose of this parameter is to prevent replay attacks and has some implementation suggestions around using http only cookies.

I understand what replay attack is in general, but I'd like to get a better understanding of the details of what a replay attack this might protect against might look like, so I can have a better idea about whether I have implemented it effectively, or made some subtle mistake.

I assume the replay attack is against the authorize endpoint, for some third party to get a token corresponding to a different user. Is that it or is it something else? What level of information do we expect the attacker has to replay? Do they have the traffic between the user agent and authorization server but not the client application, which is why they'd be able to replay the traffic to the authorize endpoint but would not be able to replay previous a cookie to the client application? Or they have the browser history of both but not the network traffic so they don't have old cookie values? Does it matter whether or not the user agent still has the previous user's session with the authorization server when the replay occurs? If the previous user does have a valid session with the authorization server and the attacker has access to that, can't they get access to a token without doing a replay? If they don't have a valid session with the authorization server, won't the user be prompted anyway, even if they replay an old request? If the user will be prompted to authenticate, presumably with credentials they don't have, what's the danger of a replay?

I have done a lot of searching and there are some similar questions (Replay attack example for validating nonce? and Purpose of nonce validation in OpenID Connect implicit flow) neither of these actually answers the question about how does this specific replay attack work. The first just quotes the recommended implementation form the spec, then talks about leaked tokens, which seems different from a replay attack to me (if the attacker has a leaked token, haven't they already won anyway?). The second explains the general idea of a replay attack, but doesn't talk about how this particular attack actually works.

As some background I'm making an openid connect app using the authorization code flow (so replaying the redirect from the AS to my app shouldn't do anything because you can only exchange the same authorization code for a token once AFAICT, so you would need to replay the authorize endpoint as well for a replay attack to be meaningful.) My app is using tokens I get back as bearer tokens to authenticate requests to my web server, and they are the entirety of the session state, there is no other meaningful session state or locally managed identity to tie the tokens to. My openid connect provider requires a nonce because it's a security best practice. Is it actually useful in my particular use case? Is the reason I'm so confused because doesn't actually provide meaningful protection for the particular thing that I'm doing? If this does have security implications for me I 110% want to make sure I do the right thing but I'm having a very hard time understanding what it protects me against.

Some implementation detail questions I'm fuzzy on due to not understanding the threat vector exactly:

  • Do I validate the nonce matches what was sent to the authorize endpoint after pulling it back from the token endpoint and then assume it's good for the session? Or should validating the id_token cookie against the nonce cookie be part of every request just like checking the signature?
  • The nonce is supposed to be tied to the session but the term nonce implies it should only be used once. If I need to send a user with a valid session back through the authorize endpoint for some reason (get a new id_token with an expiration further in the future? Request a wider set of scopes?) do I create a new nonce? Is it one nonce per session or per call to authorize?
  • It should be one nonce per call to authorize. – Michael Freidgeim Oct 8 '17 at 11:16

The nonce in question is designed to be related to the HTTP session which is by default out of scope when creating an OpenID token. By HTTP session data is not used to link an OpenID token, which allows a theoretical attacker to sniff an Open_ID token from the network and attempt to "Replay" the credentials against the authorizing server for access. This will succeed because the OpenID IDP has no given methods for identifying a source other than the signature within the token by default.

To counter this, OpenID allows for the authorizing server to leverage this end point authentication nonce to combine the HTTP Session cookie which is only known at the server/client level as a hash value. Assuming the session id is unique and randomly generated per session, this causes an issue for a would be attacker. When the attacker attempts to replay the credentials, they must guess the hash value for the HTTP session the original user had.

Reading through the notes from OpenID on this are helpful:


The biggest factors should be:

  • The NONCE value should be based on a SECURELY generated random string
  • The NONCE value should never be used twice
  • The NONCE value should tie something the server knows about the client and can keep secret.

I hope this helps.

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.