hydra
hydra copied to clipboard
Calling end_session_endpoint with id_token_hint errors when JWK is rotated
Preflight checklist
- [X] I could not find a solution in the existing issues, docs, nor discussions.
- [X] I agree to follow this project's Code of Conduct.
- [X] I have read and am following this repository's Contribution Guidelines.
- [X] I have joined the Ory Community Slack.
- [X] I am signed up to the Ory Security Patch Newsletter.
Ory Network Project
No response
Describe the bug
After creating/rotating a new JWK, when existing sessions call the end_session_endpoint
with the id_token_hint
Hydra is redirecting to the error page with the following error:
error: invalid_request
error_description: The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. go-jose/go-jose: error in cryptographic primitive
Reproducing the bug
- Successfully login and retrieve an
access_token
andid_token
from Hydra. - Create a new JWK by making a
POST
call to/admin/keys/hydra.openid.id-token
- Logout from the application being redirected to the
end_session_endpoint
withid_token_hint
populated. - Hydra redirects to the error page with error:
The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. go-jose/go-jose: error in cryptographic primitive
Relevant log output
time=2024-02-15T23:03:15Z level=error msg=An error occurred audience=application error=map[debug: message:invalid_request reason:go-jose/go-jose: error in cryptographic primitive status:Bad Request status_code:400]
Relevant configuration
No response
Version
2.2.0-pre.1
On which operating system are you observing this issue?
None
In which environment are you deploying?
None
Additional Context
Digging into the code this is the trail I found:
- Logout Handler calls:
h.r.ConsentStrategy().HandleOpenIDConnectLogout(...)
: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/oauth2/handler.go#L129 - calls
s.issueLogoutVerifier(...)
because nologout_verifier
was passed: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/consent/strategy_default.go#L1091 - calls
s.getIDTokenHintClaims(...)
with id token: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/consent/strategy_default.go#L878 - calls
s.r.OpenIDJWTStrategy().Decode(ctx, idTokenHint)
usingjwk.NewDefaultJWTSigner()
: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/consent/strategy_default.go#L173 -
NewDefaultJWTSigner
sets aGetPrivateKey
func to essentially: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/jwk/jwt_strategy.go#L42-L57 -
GetOrGenerateKeys(...)
called by theGetPrivateKey
func and callsFindPrivateKey(...)
: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/jwk/helper.go#L46-L78 -
FindPrivateKeys(...)
removes public keys and returns the First key in the set: https://github.com/ory/hydra/blob/0421fdad0b30b24a1aa5939e69c20e9d0d8b649f/jwk/helper.go#L96-L103
This is where the issue lies, because the active id_token
is no longer the first
token anymore since the JWK was rotated. It seems the id_tokens
KID
should be pulled out along the way at some point and passed in so the proper key is found instead of the first
one found.
Hello. Is there any confirmation that this is indeed a bug? I can potentially find time to look further into this if confirmation is given.
Thank you
Yes, this does look like a bug. Instead of only using the first key, we should attempt verification with previous keys as well.
PRs are welcome.