superset
superset copied to clipboard
exp claim on JWT token is not respected and token is still valid after expiration time
Bug description
Using my Superset secret key, I generated a JWT token for API access. The exp
claim is not respected.
From terminal:
❯ date +%s
1715592489 # note that this is bigger than exp claim in above screenshot
❯ curl -X 'GET' \
'https://superset.xxx.com/api/v1/dataset/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
{"count":2, ...} # curl should have returned that token has already expired
Just as a sanity check, I added a nbf
claim that is far into the future and it is respected.
❯ curl -X 'GET' \ 18:28:09
'https://superset.xxx.com/api/v1/dataset/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...with_nbf'
{"msg":"The token is not yet valid (nbf)"}
How to reproduce the bug
- Have a running instance of Superset.
- Generate a JWT token with
sub
,iat
, andexp
claims.exp
should be expired andsub
should be a user id fromab_user
table with access to API calls (admin user works fine). https://jwt.io/ can be used for token generation. - Run
curl
command from terminal with headerAuthorization: Bearer {jwt_token}
as in above bug description. -
curl
should return response that token has already expired but it returns actual results instead.
Screenshots/recordings
No response
Superset version
4.0.0
Python version
Not applicable
Node version
Not applicable
Browser
Chrome
Additional context
No response
Checklist
- [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
It appears the issue with the JWT exp
claim not being respected in Superset might stem from how the JWT decoding process is handled within the application. Superset uses the jwt.decode
method for decoding JWT tokens, relying on the JWT library's default behavior to validate the exp
claim. If the JWT library's default behavior is overridden or not configured correctly to enforce exp
validation, Superset might not respect the expiration time of the token.
The relevant Superset code does not explicitly check the exp
claim during the decoding process. Instead, it relies on the JWT library to perform this validation. This means that if there's a misconfiguration in the JWT library or an issue with how Superset is using it, the exp
claim might not be properly validated.
Furthermore, Superset has mechanisms, such as the SupersetSecurityManager
class, that can influence JWT validation, including handling of the exp
claim. These mechanisms allow Superset to implement custom logic for token expiration and validation, which could potentially override the default JWT library behavior.
To address this issue, you might want to review your Superset and JWT library configurations to ensure they are set up correctly to validate the exp
claim. Checking the version of the JWT library and any relevant Superset settings related to JWT token handling could also provide insights into the problem. If the configurations appear correct, this might indicate a bug in Superset or the JWT library regarding exp
claim handling.
Details
Sources
- superset/utils/oauth2.py
- superset-embedded-sdk/src/guestTokenRefresh.test.ts
- superset-embedded-sdk/src/guestTokenRefresh.ts
- superset/security/manager.py
About Dosu This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.
Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.
To continue the conversation, mention @dosu.
I was not able to reproduce the issue
JWT used:
{
"fresh": true,
"iat": 1715600519,
"jti": "0072e7d4-cfc1-4ca3-a910-2b66fd957ea8",
"type": "access",
"sub": 1,
"nbf": 1715600519,
"exp": 1715601419
}
curl -X 'GET' \
'http://localhost:8088/api/v1/dataset/' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJhbGci....'
{
"msg": "Token has expired"
}
$ date +%s
1715604341
This was my mistake. The timestamp I used was in milliseconds when it should have been in seconds. So the expiration was off by orders of magnitude. Thank you for the assistance! Closing the issue.