Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal/discussion: OIDC requirement about ID token only being used to prove that the user has been authenticated (edit: a general requirement for allowing only intended usage for tokens) #2005

Closed
deleterepo opened this issue Jul 27, 2024 · 19 comments
Assignees
Labels
1) Discussion ongoing Issue is opened and assigned but no clear proposal yet V51 Group issues related to OAuth Will be closed if no response/opposite arguments _5.0 - prep This needs to be addressed to prepare 5.0

Comments

@deleterepo
Copy link

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/:

Access tokens may be either "bearer tokens" or "sender-constrained" tokens. Sender-constrained tokens require the OAuth client to prove possession of a private key in some way in order to use the access token, such that the access token by itself would not be usable.

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.

@randomstuff
Copy link
Contributor

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?)

@elarlang
Copy link
Collaborator

elarlang commented Jul 28, 2024

Based on my understanding the typ must be checked for that and I have addressed the topic in the issue: #1967

ping @deleterepo @randomstuff - do you think/agree that checking the typ solves the issue or we need some additional requirement for that?

@tghosth tghosth added 1) Discussion ongoing Issue is opened and assigned but no clear proposal yet _5.0 - prep This needs to be addressed to prepare 5.0 V51 Group issues related to OAuth labels Jul 29, 2024
@randomstuff
Copy link
Contributor

randomstuff commented Jul 29, 2024

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.

@elarlang
Copy link
Collaborator

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.

@jmanico
Copy link
Member

jmanico commented Aug 17, 2024 via email

@randomstuff
Copy link
Contributor

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.

@elarlang
Copy link
Collaborator

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".

@elarlang
Copy link
Collaborator

This discussion here covers also #2049 and I closed this one to find the solution here.

Probably best requirement proposal was in #2049 (comment)

Verify that only access tokens can be used for authorization, not other kinds of tokens like ID Tokens or Logout tokens.

@elarlang
Copy link
Collaborator

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?

@TobiasAhnoff
Copy link

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.

@elarlang
Copy link
Collaborator

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).

@elarlang
Copy link
Collaborator

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.

@elarlang
Copy link
Collaborator

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 elarlang added the 4) proposal for review Issue contains clear proposal for add/change something label Sep 15, 2024
@elarlang elarlang changed the title Proposal/discussion: OIDC requirement about ID token only being used to prove that the user has been authenticated Proposal/discussion: OIDC requirement about ID token only being used to prove that the user has been authenticated (edit: a general requirement for allowing only intended usage for tokens) Sep 15, 2024
@elarlang elarlang added the V3 label Sep 15, 2024
@tghosth
Copy link
Collaborator

tghosth commented Sep 15, 2024

@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.

@elarlang
Copy link
Collaborator

elarlang commented Sep 15, 2024

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.

@elarlang elarlang removed the 4) proposal for review Issue contains clear proposal for add/change something label Sep 16, 2024
@tghosth
Copy link
Collaborator

tghosth commented Sep 17, 2024

I would still like @ryarmst's input here as this is also a requirement that feels quite specific to OAuth

@randomstuff
Copy link
Contributor

randomstuff commented Sep 17, 2024

For example, ID tokens can only be used to prove user authentication for the client.

I think a counterexample would be more useful. « For example, ID tokens can cannot be accepted by resource servers. »

Otherwise people won't notice that when they are using the ID token on the RS, they are not actually « only using the ID token to provide user authentication for the client ».

@elarlang
Copy link
Collaborator

@randomstuff - I think this is other and separate problem.

But to have smooth(er) and fast(er) development process, I'll add this requirement to V51 and OAuth chapter.

@elarlang
Copy link
Collaborator

The requirement is now in the document via #2089

# Description L1 L2 L3
51.1.1 [ADDED] 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.

If there are no immediate improvements needed, for me it seems we can close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1) Discussion ongoing Issue is opened and assigned but no clear proposal yet V51 Group issues related to OAuth Will be closed if no response/opposite arguments _5.0 - prep This needs to be addressed to prepare 5.0
Projects
None yet
Development

No branches or pull requests

6 participants