-
Notifications
You must be signed in to change notification settings - Fork 380
Description
Preflight checklist
- I could not find a solution in the existing issues, docs, nor discussions.
- I agree to follow this project's Code of Conduct.
- I have read and am following this repository's Contribution Guidelines.
- I have joined the Ory Community Slack.
- I am signed up to the Ory Security Patch Newsletter.
Ory Network Project
No response
Describe the bug
The validation behavior for JWT claims is inconsistent in fosite:
- https://github.com/ory/fosite/blob/master/token/jwt/map_claims.go#L110
fosite/handler/rfc7523/handler.go
Line 226 in 8052806
func (c *Handler) validateTokenClaims(ctx context.Context, claims jwt.Claims, key *jose.JSONWebKey) error {
The first one checks that:
- nbf <= now (if present)
- iat <= now (if present)
- exp >= now (if present)
- whether these claims are required is hardcoded to false
The second one checks that:
- nbf <= now (if present)
- iat is present (configurable)
- (exp - now) <= JWT Max Duration (if iat is not present)
- (exp - iat) <= JWT Max Duration (if iat is present)
The consequence of this is that you can issue JWT for urn:ietf:params:oauth:grant-type:jwt-bearer
that is issued in future. So the JWT with following claims will be considered valid:
- nbf = now (or absent)
- iat = now + 9000000
- exp = now + 9000001
And that doesn't look right. And the first JWT claims validation procedure will reject this token.
Reproducing the bug
- Create JWT for
urn:ietf:params:oauth:grant-type:jwt-bearer
grant type with following parameteres- set nbf to current time in seconds
- set iat to current time in seconds plus 92500000
- set exp to current time in seconds plus 95000000
- Submit JWT to token endpoint, set
grant_type
tourn:ietf:params:oauth:grant-type:jwt-bearer
andassertion
to the value of JWT - In response you'll receive an access token
If you change iat to the current time then you'll be denied because JWT duration exceeded max duration.
Relevant log output
Relevant configuration
Version
v0.49.0
On which operating system are you observing this issue?
None
In which environment are you deploying?
None
Additional Context
The security implications doesn't look severe here:
- The JWT for
urn:ietf:params:oauth:grant-type:jwt-bearer
can only be used once. But they still live long. If an attacker may trick some system to generate a lot of these JWTs in advance she may use them long after. - JTIs of these long living JWTs will probably live in storage until their expiration time, so the loudy DOS attack to exhaust storage is possible.
The naive solution looks quite simple: replace this conditional operator with just issuedDate = time.Now()
. To avoid breaking things one might consider adding configurable clock skew for both validators (#651) :)