ory / fosite

Extensible security first OAuth 2.0 and OpenID Connect SDK for Go.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=fosite
Apache License 2.0
2.28k stars 356 forks source link

`iat` field in access token (JWT) issued as part of `refresh_token` grant. #774

Open tn185075 opened 8 months ago

tn185075 commented 8 months ago

Preflight checklist

Ory Network Project

No response

Describe the bug

Please assume the following flow:

Screenshot 2023-11-09 at 12 43 16 PM

Reproducing the bug

Please reproduce the above mentioned steps, with any OAuth server powered by fosite :)

Relevant log output

No response

Relevant configuration

No response

Version

v0.42.2

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Kubernetes

Additional Context

No response

james-d-elliott commented 8 months ago

Also relevant https://datatracker.ietf.org/doc/html/rfc6749#section-1.5

The refresh flow explicitly states new tokens are issued. Obviously this is void of any context regarding the JWT Profile but likely applies.

tn185075 commented 7 months ago

If approved as bug, I'd be glad to raise a PR fixing it.

tn185075 commented 7 months ago

Bumping up ‼️

mitar commented 4 months ago

I can confirm that iat gets updated in ID tokens, but not access tokens. I think you should just do a PR with tests for this.

mitar commented 4 months ago

So it looks this is more confusing than one would hope for.

For ID Tokens:

This seems reasonable. rat claim seems to be specific feature of Fosite. And it might be reasonable that it does not change on refresh. That it shows when the original ID token was requested.

For access tokens:

I find this confusing. There are two names (RequestedAt and IssuedAt) used for the same thing and also two places to save it (one in requester, the other in JWK claims).

Anyway, my workaround for this is that I set IssuedAt every time GetJWTClaims() is called.

mitar commented 4 months ago

Sorry, in fact no, it does not work correctly. By default AccessTokenJWTToRequest is not used but a standard introspection is used instead. And I tested this now and it can happen that the iat in the response is different from the iat in the JWT token. iat in the response uses GetRequestedAt, but iat timestamp in JWT is generated using time.Now().UTC().

So the problem is even in the initial access token. And another issue is that after refresh the iat is not updated.

mitar commented 4 months ago

Workaround in introspection handler:

    ar := ir.GetAccessRequester().(*fosite.AccessRequest)
    ar.RequestedAt = ar.GetSession().(*oauth2.JWTSession).JWTClaims.IssuedAt

    oidc.WriteIntrospectionResponse(ctx, w, ir)
mitar commented 4 months ago

I found another issue In HMACSHAStrategy's ValidateAccessToken, access token's GetRequestedAt is used to validate the token. But because refreshed access tokens keep original issue time, those refreshed access tokens are valid even before the real issue time (the time they have been issued).