nonce as PKCE alternative for OIDC flows

Issue #352 wontfix
Torsten Lodderstedt created an issue

AS clause 11 currently states:

„shall require PKCE [@!RFC7636] with S256 as the code challenge method“
The Security BCP and the OAuth 2.1 draft allow use of nonce as alternative to PKCE for confidential clients. This makes especially sense if the client is a OIDC RP.

I suggest we add this alternative to FAPI 2 baseline as well.

Comments (10)

  1. Joseph Heenan

    There’s been a few discussions about this in the working group in the past (FAPI1-RW also does not require PKCE in the common cases).

    I believe the general feeling (particularly after seeing a huge number of very poor RP implementations in the UK OpenBanking ecosystem that skip most/all of the client side OIDC checks) is that it’s good to always have PKCE required, as this can be enforced at the authorization server side - meaning the security properties are under the control of the OP (rather than the RP). This is better as there are fewer OPs than RPs and we’ve generally found that the OP implementations are far higher quality than the average RP implementation.

    By way of a concrete example, a UK bank was signing id_tokens with a key that was not present in their JWKS (and hence there was no way the id_token signature could be successfully verified), and this went on for several months at the end of 2019. I’m reliability informed that they got zero complaints from their RPs.

  2. Torsten Lodderstedt reporter

    I understand the rationale, however RPs can also get things wrong with PKCE as they determine the code verifier and bind it to the transaction.
    please note: nonce should be acceptable as alternative (exception) for RPs that anyway use OIDC for identity. If the OP screws up its keys in that case, well … then the whole identity flow is compromised.

    The baseline profile deviates from the Security BCP and OAuth 2.1 here. Note: the OAuth WG had a lengthy and detailed discussion about this aspect and came to the before mentioned conclusion after the discussion you mentioned took place.

    Potentially a reason to open the discussion again?

  3. Joseph Heenan

    I understand the rationale, however RPs can also get things wrong with PKCE as they determine the code verifier and bind it to the transaction. 

    How many ways can it go wrong? I can only see three errors the RP could make:

    1. Using the same code verifier in multiple transactions
    2. Using different but predictable code verifiers for transactions
    3. Other mistakes that will make the token endpoint call fail due code_verifier validation failing

    ‘1' is an obvious security problem but I believe the AS could detect it (however I’m not sure if any existing implementations do).

    ‘2' could be a problem, and feels quite hard to detect at the AS. I’m not sure how likely it is to result in a practical attack. I suspect it might be mostly defendable against at the AS if it has protections against brute-force attacks.

    '3' is not a security problem.

    Did I miss any cases?

    Potentially a reason to open the discussion again?

    Absolutely.

  4. Torsten Lodderstedt reporter

    to 1: the AS could detect it but that comes at a cost. The AS would need to keep track of all used verifiers - cluster wide. That sounds like a bottleneck.

  5. Joseph Heenan

    Agree there’s a cost. I would probably argue there’s a low cost solution as there’s a few helpful properties:

    1. You don’t need to detect every duplicate
    2. You don’t need to detect the duplicates in real time (there’s no real significant risk if you don’t disable a client till a few hours after it used duplicates)
    3. You probably only need to check the first few times after a new client is onboarded

    I’m not sure how important this point is. Failing to check nonce correctly is an act of omission (it’s not necessary to check nonce for the client to work so lazy/uninformed people skip it). With PKCE the client has to implement it (if the AS requires it). They could still implement it badly, but I’d argue it’s more likely they do a correct enough implementation of PKCE than a correct implementation of nonce checking.

  6. Daniel Fett

    In OAuth 2.1, nonce is not treated as an equal alternative, but comes with an important caveat:

    the
       following criteria are met:
       (...)
    In the specific deployment and the specific request, there is
          reasonable assurance for authorization server that the client
          implements the OpenID Connect "nonce" mechanism properly.
    

    And even then, PKCE is still RECOMMENDED.

    Given this, the potential for downgrade-attacks, and Joseph’s remarks, I would very much welcome PKCE as always mandatory in FAPI 2.

  7. Brian Campbell

    I would favor keeping PKCE always mandatory in FAPI 2. Having fewer switches and optionality, when possible, is good. And this seems imminently possible. FAPI 2 is mostly about APIs and just the OAuth layer and as such reliance on or exceptions for OIDC level stuff should be minimized. FAPI 2 is also “new” so doesn’t necessarily have to account for legacy situations with special cases like this. Expecting a Client that’s an OIDC RP that also wants to be FAPI 2 to use or start using PKCE is not unreasonable at all.

  8. Log in to comment