OpenID4VCI icon indicating copy to clipboard operation
OpenID4VCI copied to clipboard

Additional options for wallet-provided nonces for PoP

Open awoie opened this issue 1 year ago • 13 comments

On the DCP WG call on June 27th, we concluded that c_nonce is in fact optional. To mitigate the attack discussed here https://github.com/openid/OpenID4VCI/issues/19 without a c_nonce, several options were brought up and we agreed to create a dedicated issue for this.

Some options are:

  1. ath (access token hash)
  2. jti (chosen by the wallet with enough entropy)
  3. nonce (keep nonce in PoP but allow wallet-generated nonces similar to jti; probably not a good idea because in some situations/policies a server might fail distinguishing between c_nonce values and wallet-generated nonces in the nonce claim)

(cc @David-Chadwick @Sakurann @jogu @bc-pi @babisRoutis)

awoie avatar Jun 27 '24 16:06 awoie

The ath indeed has limitations, as it is typically applicable only to the first HTTP request made to the Resource Server (RS).

From a security and design perspective, when the RS supports the issuance of multiple credentials using the same Access Token (AT), it is practical to issue a c_nonce in the RS's response; in this way the RS hints the client about its support of multiple issuance with the same AT. This c_nonce should then be expected in the next request to the RS, utilizing the nonce parameter.

Given these considerations, I support option 2, using the jti (JWT ID). This choice avoids conflicts with the optional nature of the nonce during the initial request and aligns with the requirement for a nonce in subsequent requests if it is provided in the RS's response.

peppelinux avatar Jun 27 '24 23:06 peppelinux

The ath indeed has limitations, as it is typically applicable only to the first HTTP request made to the Resource Server (RS).

@peppelinux Can you please clarify - to understand your comment - whether the RS term corresponds to the Credential Issuer (protected endpoints)?

babisRoutis avatar Jun 28 '24 11:06 babisRoutis

@babisRoutis yes, the credential endpoint is an RS in the OAuth 2.0 paradigm

peppelinux avatar Jun 28 '24 11:06 peppelinux

I think the jti variant makes sense.

Would this be a purely Wallet side mechanism, no Issuer involvement needed?

nemqe avatar Jun 30 '24 01:06 nemqe

@nemqe yes jti is self-issued by the issuer, it's a pure identifier that uniquely identifies a JWT within its issuer

a non-exaustive comparison between nonce and jti was outlined in the following I-D: https://peppelinux.github.io/draft-demarco-oauth-nonce-endpoint/draft-demarco-oauth-nonce-endpoint.html#name-considerations-about-nonce-

peppelinux avatar Jun 30 '24 11:06 peppelinux

@peppelinux I was thinking more about who is protecting who in this case.

Wasn't sure where the responsibility for safety of this interaction lies, and if the Issuer will need to keep track of jti values so it guarantees that no same value has been used during the session or not or will it be ok if the Issuer does not care at all.

nemqe avatar Jun 30 '24 11:06 nemqe

@nemqe

jti unlike nonce is not absolute but relative to its issuer

nonce is absolute because who evaluates its uniqueness is at the same time its issuer

jti is "unique together" with its issuer and who evaluates its uniqueness must keep track of it until the jwt in which it is contained is active and not expired (or revoked, see introspection endpoint)

for this reason nonce is cheaper, because we "suppose" that a jwt may have a longer lifetime of a nonce that is it issued just in time for a specific transaction, where this transaction assumes a short duration.

I support jti to uniquely identify a jwt, together with its issuer, like a best practice (you see in all the italian specs its presence).

peppelinux avatar Jun 30 '24 12:06 peppelinux

the RS is the party that must protect itself from replay attacks, therefore it should keep track of jwts against any replay of these, until the jwts expires.

peppelinux avatar Jun 30 '24 23:06 peppelinux

It is also possible to include both, ath and jti which would mitigate @peppelinux concern that ath would be the same during the lifetime of the access token. Using both has the advantage to have something the holder chose and something the AS chose.

awoie avatar Jul 01 '24 09:07 awoie

These options remind me DPoP

DPoP JWT contains jti, ath and .. nonce (among other claims).

Anyway, with regards to the issue I strongly believe that a single mandatory solution would be better than have multiple alternative (yet optional) choices.

Should c_nonce be kept? Then:

  • Then remove it from the token endpoint
  • Make it mandatory to proofs
  • Make it mandatory to credential error response
  • Make it optional to credential success response (in case issuer supports continuing issuance with the same AT)

if c_nonce is considered, on the other hand, optional, let's remove it from spec and define a single alternative (jti, jti+ath, or something else)

babisRoutis avatar Jul 01 '24 10:07 babisRoutis

Small brain dump, I apologize in advance for possibly saying things people know, have discussed, or just plain incorrect things

The way I see it:

  • Request payloads can be replayed
  • Proofs can be replayed

ath in the proof should prevent the proof-replay of the initial request (token header alone should prevent request-replay)

Being a defensive Wallet I might not trust the Issuer and his way of generating tokens, and for this reason I would want to introduce a jti into the proof because now I also participate in ensuring the safety on my communication.

Now the problem with a jti is that I as an Issuer might not trust the value provided by the Wallet. Problem is not only checking that a jti is unique during a 'session' but also ensuring that the same jti has not been used with some other Issuer. Because of this as an Issuer I want to add a c_nonce for subsequent requests.

Meaning:

  • for the initial request i see a ath + jti scheme
  • for subsequent requests I see a ath + jti + c_nonce scheme

nemqe avatar Jul 01 '24 12:07 nemqe

Meaning:

  • for the initial request i see a ath + jti scheme
  • for subsequent requests I see a ath + jti + c_nonce scheme

@nemqe I believe I agree with this.

@babisRoutis on removing c_nonce from token endpoint, let's have the discussion in this other issue https://github.com/openid/OpenID4VCI/issues/39

awoie avatar Jul 01 '24 14:07 awoie

this probably supersedes/relates to #19 ?

Sakurann avatar Oct 28 '24 20:10 Sakurann