Open deleterepo opened 1 month ago
Verify that the ID token is only used to prove that the user has been authenticated, and is not accepted as an authorization token by the Resource Server.
And the other way around? Verify that access tokens are not recognized as ID token?
In addition, would any requirement against ID token / access token cross-JWT confusion make sense? (such as making sure that "aud" values are different for ID tokens and for access tokens?)
Based on my understanding the typ
must be checked for that and I have addressed the topic in the issue: https://github.com/OWASP/ASVS/issues/1967
ping @deleterepo @randomstuff - do you think/agree that checking the typ
solves the issue or we need some additional requirement for that?
do you think/agree that checking the typ solves the issue or we need some additional requirement for that?
AFAIU, this is not really enough (not as simple as that) in general because OpenID ID token does not mandate any typ
. As far as I understand, the type might be missing but a type might be present. It might be JWT
(which is very general) or could be something else (?).
In addition, while RFC 9068 requires using application/at+jwt
for JWT access tokens, it nos always used in practice.
For example, Keycloak currently uses 'typ': 'JWT'
for both access tokens and ID tokens.
The wording needs (a lot of) work, but maybe this as a direction: Verify that the token is made for that type of usage before accepting it, such as an ID token for authentication and an access token for authorization without allowing cross-usage.
How about: (this is a bit too verbose but a step in the right direction I think)
Verify that tokens are used according to their intended purpose: ID tokens should be used exclusively to prove authentication, while access tokens should be used strictly for delegation or authorization. Ensure that cross-usage between ID tokens and access tokens is explicitly disallowed.
This is not very directly actionnable but is it not very easy to make this more actionnable.
What about:
Verify that ID tokens issued or consumed by the system cannot be used as JWT access tokens. The can for example be achieved by using different values for the
iss
claims (eg. opaque client_id for ID tokens and server URI for the access tokens).Verify that JWT access tokens issued or consumed by the system cannot be used as ID tokens. This can for example be achieved by using different values for the
iss
claims (eg. opaque client_id for ID tokens and server URI for the access tokens).
Or more detailed formulation:
When consuming an ID tokens, verify that JWT access tokens cannot be used instead. This can be achieved by requiring the usage of a nonce.
When consuming a JWT access tokens, verify ID token cannot be used instead. This can be achieved by requiring the presence of a suitable
scope
claim value.When producing an ID token, verify that it cannot be interpreted as a JWT access token by the consuming application (HOW?)
When producing a JWT access token, verify that it cannot be interpreted as an ID token by the consuming application (HOW?)
None of these formulations cover the other cases of JWT token mixup.
I think this direction goes to the cheat sheet side, we are not limited to id-token and access token, but can add refresh token into the mix.
Also a bit the point of view - "Verify that ID-token can not be used as access token" vs "Verify that only valid ID-token can be used as ID-token".
This discussion here covers also #2049 and I closed this one to find the solution here.
Probably best requirement proposal was in https://github.com/OWASP/ASVS/issues/2049#issuecomment-2336813309
Verify that only access tokens can be used for authorization, not other kinds of tokens like ID Tokens or Logout tokens.
My attempt for catch all requirement:
Verify that tokens (such as ID tokens, access tokens and refresh tokens) can only be used according to their intended purpose without allowing cross-usage between them.
ping @randomstuff @TobiasAhnoff - any (dis)agreements or feedback?
Verify that tokens (such as ID tokens, access tokens and refresh tokens) can only be used according to their intended purpose without allowing cross-usage between them.
I agree, but perhaps it would be good with one example (like @jmanico suggested) to make it clearer, even if it does not list all scenarios and technical details, it highlights (in my experience) the most common token-confusion, like this
Verify that tokens (such as ID tokens, access tokens and refresh tokens) can only be used according to their intended purpose without allowing cross-usage between them. In example ID tokens should be used exclusively to prove user authentication for the client.
We can list examples if needed.
General feedback - the context for ASVS requirement is "strong true of false requirement" (must), but not recommendation (should). So the language must be more strict, instead of "should be" we can use "can only be" or "must be" (see also https://datatracker.ietf.org/doc/html/rfc2119).
For the section, the requirement is valid for OAuth and OIDC and may be more general token validation, although it mentions OAuth-specific tokens as examples.
To make it more clear and "actionable". My proposal is to add the proposed requirement as a general token requirement to to V3.5:
Verify that tokens (such as ID tokens, access tokens and refresh tokens) can only be used according to their intended purpose without allowing cross-usage between them. In example ID tokens cam only be used to prove user authentication for the client.
ping @TobiasAhnoff @deleterepo @tghosth @randomstuff
@elarlang
Verify that tokens (such as ID tokens, access tokens and refresh tokens) can only be used for their intended purpose. For example, ID tokens can only be used to prove user authentication for the client.
That would be my suggestion. I think this sounds like L3 to me. I would also tag @ryarmst as he is looking at V3.
This is for sure L1. It's pretty much the same as checking that the token is in a valid time window (not expired).
V3 as a category here is questionable, as these kinds of token-questions are not really session management questions.
Developers sometimes mix up ID tokens and access tokens, especially in first-party scenarios, such as the case where both the client and the resource server, such as an API, is under their control. Using the ID token to make authorization decisions is a security issue, as there is no mechanism that ties the ID token to the API. Thus if an attacker steals the ID token in this case, they can use it to act as a legitimate client and call the API. For access tokens, these can be "sender constrained", such that the access token is bound to a specific sender. If an access token is stolen, an attacker can't necessarily use it to access the API since the token can be bound to the original client that requested it. From https://oauth.net/2/access-tokens/:
Another way of looking at this is the audience claim for each token. For the ID token, the intended recipient is the client, whereas for the access token, it's the RS. That's a lot to digest 🤢, but the requirement itself can be as simple as this: Verify that the ID token is only used to prove that the user has been authenticated, and is not accepted as an authorization token by the Resource Server.