Reputation: 600
In the context of user authentication using OIDC/OAuth 2 with Authorization Code + PKCE in a web-based Single Page Application (SPA), a nonce parameter can be generated and sent to the identity provider to mitigate replay attacks.
https://oa.dnc.global/-OpenID-Connect-Autorisation-via-un-code-Authorization-Code-Flow-.html
While the nonce parameter is mandatory for the now-obsolete implicit flow, it's optional for the authorization code flow.
What are the potential attack vectors if the nonce parameter is not used?
The SPA can validate that the ID token is invalid if the nonce claim in the JWT doesn't match, but when an attacker can send a valid but stolen ID token to the SPA?
Upvotes: 3
Views: 893
Reputation: 1140
TLDR;
nonce
is meant to provide protection against authorization code injection attacks, BUT it doesn't provide this protection in the case of public clients, e.g., SPA's.
For an explanation of what protection the nonce
parameter provides, have a look here:
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#nonce_as_injection_protection
The last paragraph addresses your question with regard to what protection nonce
provides specifically for public clients, e.g., SPAs:
It is important to note that nonce does not protect authorization codes of public clients, as an attacker does not need to execute an authorization code injection attack. Instead, an attacker can directly call the token endpoint with the stolen authorization code.
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.5.3.2-4
The following section then addresses the next concern, i.e., "If the nonce
parameter doesn't provide protection for public clients, then what should I use? "
PKCE is the most obvious solution for OAuth clients as it is available today (originally intended for OAuth native apps) whereas nonce is appropriate for OpenID Connect clients.
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.5.3.3-2
Now, if you're asking what the difference between PKCE and nonce
is and why PKCE can protect public clients while nonce
cannot, the difference is the different steps of the OAuth/OIDC flow where they come into play.
The nonce is generated by the client and sent in with the authorization request similar to how the code_challenge
and code_challenge_method
(optionally) in PKCE. The OpenIdentity Provider (OP - the authorization server) stores the value(s) and returns the authorization code. However, what follows differs.
Using nonce
:
authorization code
to the OP.nonce
received in the authorization request into the (ID
) token and returns the tokennonce
value in the token with the value in session storageUsing PKCE:
authorization code
AND the code_verifier
to the OPcode_verifier
by transforming it with the code_challenge_method
and checking if it matches the code_challenge
received previously.I bolded the steps where the "protection occurs" for each. Using nonce
the burden is more on the client to verify the nonce
value in the token matches what it created and stored earlier. With PKCE, the OP does the work with the code_verifier
transformation and compares it to the earlier code_challenge
.
If a malicious client is able to steal the authorization code, there is no protection against that client getting a token and using it. It doesn't have to check the nonce
parameter. It doesn't care. But, with PKCE, the malicious client needs to have the code_verifier
or the OP will not return a token.
Upvotes: 5