-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Refresh the verification JWK sets on demand #5003
Comments
Keys don't need to be loaded periodically, but rather on-demand. Basically if there is an unknown kid try to fetch keys again. Otherwise there would be a period between keys being rotated on the server side and not being available in the client. |
Keep in mind that this can be used as an attack vector for a DoS since the application will do a http call when it encounters an unknown key.
Look at the JWKS keys returned by for instance google: They return two keys. When a key is rotated the following happens:
By taking the JWT's expiry into account in combination with cache control headers, the issuer can rotate a key without there being a period where clients is unaware of the new key. |
Vertx has a load JWKs method which gets the new set and I'd like to have a Timer task calling it at the configured period of time. (My initial assumption the introspection is done on every request was wrong by the way, Vertx would only do it for the opaque tokens). |
You don't want to use a timer task to fetch keys. Keys are rotated at a fairly irregular time (monthly, not daily), and a timer would either be far to regular, or it could end taking way to long before new keys are fetched. As such what you want is to do it on demand when you see a new KID as I mentioned earlier. Of course like everything else you want to have some protection against a DoS attack. A basic approach in this case is to have a configurable minimum time between each request. |
@stianst Hi, sure, for the latter I was indeed thinking of having a property which even allows such an on demand request, that would be a start. Plus the other property you suggest :-) |
@stianst Hi Stian, by the way, can you please remind about the idea of caching the access tokens for |
@stianst Yes, I see it being documented that they can be rotated just few times per the year by default :-) |
On demand requests should by enabled by default. I see no reason of a timer based approach in addition. What purpose does it serve? It would only serve a purpose for an application with very few requests, and with a short interval on the timer. Makes no sense IMO. |
@sberyozkin I'm not really following what you are talking about caching the access token. Are you talking about caching token introspection endpoint results? |
@stianst Right I have abandoned the timer idea for now and PR in the works to the support an on-demand pull. The tricky bit is how to test it :-). |
@stianst @pedroigor Unfortunately it is not possible to implement refreshing on demand What I'd like to do is to add a property if The possible problem with reloading on a generic verification failure is that if the attacker provided a token with the randomly modified signature which would be known to fail then when the good client call fails due to Vertx having no uptodate cache, quarkus-oidc will fail such a client if the refresh has happened just few mins earlier and will continue blocking until So it looks like we really need to know, before refreshing the keys, that the reason the verification has failed is because there were no key with a matching @stianst sorry, I keep getting back now to the idea of the timer, I get it it will be too regular and might miss badly the recent rotation :-) but it is a low cost tool, will run every month or few months and likewise might get the latest rotation on its own thread just in time before the client with the stale token kid fails and saving it waiting for the refresh call :-). It won't harm and will be optional of course. |
Actually, if the attacker has caused a refresh just a few mins before the good client token with a stale kid arrives then there would be no harm, the good client would just get a matching JWK. |
All I can do is say again that this approach is completely wrong. When verifying a token the jwt header is important. Only keys that march kid, alg and use should be considered. Anything else is a security risk. New keys must be fetched on demand. Otherwise you will have issues everytime keys are rotated at the idp. |
Adding any measurements to protect against a dos with invalid keys should be in terms of minutes, not hours or days. The longer this value is the bigger risk that you are actually creating a dos yourself. Fail to fetch keys and your not fetching the new keys for days will result in service unavailability in that period of time. Fetching keys is not a massively expensive operation, especially not it you don't parse kids you already have parsed. |
@stianst thanks, I think I indirectly came to a similar conclusion above but I did not suspect that making this refresh interval in minutes was in fact the best solution, interesting. |
So this is a plain bug in Vert.x, there really is no discussion about that, if you open a bug against Vert.x and it is rejected let me know and I'll comment on it, as it is important to pick the correct key from a JWKs set, not just randomly check them all. If keys where supposed to be loaded by trial-and-error they wouldn't have done a header in JWTs ;) |
Hi Stian I'm sure the Verx guys will support us :-) as they have done before. OK, let me deal with it. thanks |
@stianst I was not quite correct, |
@sberyozkin that's okay then. Calculating kid is probably there for some weirdness we had in Keycloak in the olden days, can probably be removed. There's nothing standard on how a kid is generated really so can never be portable cross different IdPs and Keycloak has had the kid in the token for a long time now. |
Description
As discussed with Paulo and Pedro, the adapter should try to optimize the token verification process by caching the JWK keys while also refreshing them periodically to support the key rotation
CC @pedroigor @stianst
The text was updated successfully, but these errors were encountered: