When I'm using the authorization code flow with PKCE do I still need state and nonce?

For state (that prevents login-csrf), if an attacker sends me a malicious Authorization Response, the client may accept the response, but in the end no token can be retrieved, as the code_verifier would not match the one for the code (as this was generated by the attacker).

For nonce the same is valid as far as CSRF is concerned.
For code injection attacks, an attacker that has stolen a valid code through a redirect can't make the client to exchange it to a token, as the client would not know the code_verifier for the code in the current context.

Is my reasoning correct? Am I missing some attack scenario?

1 Answer 1


My answer tries to give a short sum up of the most important information, based on Daniel Fett's article "PKCE vs. Nonce: Equivalent or Not?". For a detailed descirption of attacker models and in-depth attack descriptions, please refert to this article.

Protection against CRSF and Code Injection

PKCE and nonce both protect against most CSRF attacks, but there are edge cases where nonce provides less security, c.f. the previous mentioned article. While Nonce and PKCE provide both safety against code injection for confidential clients, public clients must use PKCE to protect against code injection.

Why you might want to use an additional nonce

You may want to comply with the specification. Following the OpenID Connect Core specification, the nonce is required for hybrid and implicit flow.

Why you might want to use an additional state

The state provides security against attacker-forged error responses, which is not prevented by PKCE specification:

When state is used for CSRF protection, OAuth error responses from the authorization endpoint must contain this parameter as well, providing protection against attacker-forged error responses. If only PKCE or Nonce are used for CSRF protection, error responses can be spoofed. [df20]

However, by simlpy returning the code_challenge on error, PKCE can be hardend against this attack.

Attention using PKCE & state & nonce together!

It is totaly possible to use those three together, but there are some pitfalls regarding the verification.

To avoid sidestepping or downgrading the PKCE and Nonce checks, authorization servers and clients need to agree on and continuously use one of the methods. For deployments with both OAuth and OIDC flows, PKCE should always be used and Nonce can be used additionally for OIDC flows.

The implementation of a combination is more complex and thus might easier lead to implementation errors. The parameter to verify needs to be choosen wisely for every situation and security goal.

  • I should have thought of looking at Daniel Fetts blog... Thank you very much!
    – BenjaminH
    Feb 17, 2021 at 7:59
  • 1
    So regular authorization code flow the most secure option is PKCE + state but PKCE alone can suffice?
    – DGK
    Jan 31, 2022 at 9:59

You must log in to answer this question.

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