Looking at this question Openid connect nonce replay attack and the answer by @benbotto. I understand the replay attack in implicit flow but unable to understand it for auth code flow. Let's say an attacker intercepts the authentication response. The attacker could then paste the response (the 302 location) into their URL bar and get your client application to make a token request. Now this request made by the client application is a server-to-server request being made using the back channel (basically it doesn't involve the user agent/browser to exchange the authorization code).

@benbotto said: "when the authorization server responds, your client application can verify the nonce in the ID token against something that your server has tied to your user's user agent (e.g. a cryptographically random value that's stored in an HTTP-only cookie)"

My question is in this case what value does the client hash, to be passed in as nonce parameter which then the Auth server would include as claims in id_token. Assuming the replay request comes in without a cookie as the attacker doesn't know the secret nonce set in the user's(victim) browser, shouldn't the request be outright rejected by the client app and not even trigger the token request?

Why is the client app tricked into requesting the token to exchange the auth code when there is no cookie(nonce) in the replayed request?

This brings me to the question are replay attacks on the client application even possible in auth code flow?

1 Answer 1


(This is a couple years late, but I'm hoping this might be useful to someone else in the future)

tldr; the OAuth authorization server helps to prevent replay attacks by ensuring that the auth code is single use only, so the nonce doesn't perform that function

Detailed explanation

Replay attacks can only occur from a server-initiated action. In the case of the OAuth 2.0 auth code flow, that means we're talking about the callback step.

In the implicit flow, a replay attack allows an attacker to get unauthorized access to the client app, because the client accepts the ID token as the proof of authentication from the identity provider.

The equivalent step in the auth code flow would be the callback step where the identity provider returns the code and state parameter in the redirect URI. Even absent of any protections on the client side, an attacker cannot make a replay attack to log into the client. Here are the steps for a successful attack:

  1. Attacker makes a replay request to the client's redirect URI with an auth code that has already been used once
  2. The client, absent of any protections, receives the auth code and proceeds to attempt a token exchange with the identity provider
  3. The identity provider rejects the request because the auth code can only be used once to exchange an access token, as per RFC 6759, section 4.1.2
  4. Because the client does not successfully complete the token exchange, the attacker is not logged in

In the implicit flow, we check against the nonce to ensure that the request is not a replay. In the auth code flow, because the replay attack is mitigated by the identity provider, the greater concern is with auth code interception (i.e. if the authorization code is intercepted before the client has a chance to exchange it for an access token). We employ different measures to protect against auth code interception:

  1. Use PKCE (enforced by identity provider)
  2. Validate the OAuth state parameter (enforced by client)

The nonce is useful in the auth code flow for defending against auth code injection, where an attacker injects their own valid authorization code into the callback URI of the client. When the client receives the ID token, they will see that the nonce received does not match the nonce that the original user agent submitted in their initial auth request, because the nonce is associated with the attacker's auth request and not the original request.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .