-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
OIDC Extension - JWKS not refreshed #12984
Comments
@missourian55 This property should be documented better, what it does is it prevents the DOS attack where an attacker manipulates Otherwise I'll be happy enough to close this issue with the PR updating this property documentation. |
@missourian55 Note as mentioned by Keycloak and other OIDC experts, the JWKs are changed in the production irregularly and also quite rarely, cc @stianst @pedroigor |
@sberyozkin thank you for the insights and the on demand trigger of JWKS refresh on kid mismatch makes sense to me. Our enterprise use an IDP which supports token introspection and general recommendation is to refresh the JWKS every 24 hours asynchronously (paranoid and it changes may be twice a year). I use keycloak to learn Quarkus OIDC security. Both jose4j and nimbus (used by spring security) both give an option to the users to control the cache settings of JWKS /*jose4j*/
@Singleton
@Produces
@Named("jwtVerifier")
public JwtConsumer jwtConsumer(@Named("jwksURL") final String jwksURL) {
final HttpsJwks httpsJkws = new HttpsJwks(jwksURL);
httpsJkws.setDefaultCacheDuration(3600 * 24);
httpsJkws.setRetainCacheOnErrorDuration(3600);
final HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
httpsJwksKeyResolver.setDisambiguateWithVerifySignature(true);
return new JwtConsumerBuilder()
.setRequireJwtId()
.setExpectedAudience(false, "account")
.setVerificationKeyResolver(httpsJwksKeyResolver)
.build();
} What is point of introspection here instead of failing the incoming request? |
So, say if a malicious user downloaded a sample access_token(get a token from here https://auth0.com/docs/tokens/access-tokens/use-access-tokens) and post a request to my quarkus service. I unnecessarily see two requests going to idp on the first attempt
subsequent attempts making a introspection calls
Seems not right to me. Any way to fail early like - unable to validate the incoming token with configured/cached JWKS and return error immediately? (without making certs or introspect remote calls to IDP) |
@sberyozkin Looks like we should fail fast the incoming request as suggested by @missourian55. |
Hi @missourian55 @pedroigor it has been discussed in depth (and I really mean it was discussed in depth :-) ), privately and publicly with @pmlopes. It is not a problem because the key rotation is not happening in production every 10 mins or so, so if it happens that 2 requests are sent in a long running application once per every few months or so then it is not a problem. @missourian55, re your last comment. If Keycloak will return a refreshed key set with the matching keys, then no, there will be no subsequent introspection requests. But it does not in your case, so obviously, without the local matching key the introspection fallback is executed. |
I agree with you on the JWKs bits. My only point is in regards to the real need to make those two requests if signature verification failed. It might open an attack surface that allows people to DoD not only the application but also the IdP ? |
Hi @pedroigor the 2nd (introspection) request will only happen once every few months (or whenever the keys are rotated) for the JWT tokens when no matching JWK is available locally. The local key unavailability does not mean the token signature is invalid. And it is not happening if the signature verification with the local matching JWK fails. |
In general, when dealing with the opaque tokens, and we have users who have such tokens, the introspection call will always go ahead - and again here the token can be randomized - but this an orthogonal issue - we'd need to keep a count of requests per client_id within a given interval etc, something which is worth considering in the future |
@sberyozkin @pedroigor
As of right now that introspection call to IDP is happening on every request with a bad access token (a token with no matching kid) I agree with @pedroigor on DoD attack on not only the application but also the IDP |
@missourian55 Please read carefully my earlier responses. When JWT with no matching kid comes in or when an opaque/binary token comes in, then the only way to verify this token is via the introspection response. In case of JWT, once the JWK refresh request has completed, there will be no follow up introspection requests as long as the local JWK is available |
@missourian55 @pedroigor Hi, I've thought more about it. So, while I don't think changing VertxOAuth2 to block the introspection requests is realistic given the earlier discussions or (IMHO) generally sound since we can have the users dealing with not only JWT but also opaque tokens (including the encrypted JWT tokens), what can be supported in Quarkus OIDC, where the users absolutely know they want the local JWK verification only, is to try to indirectly block the introspection during this forced JWK refresh interval - I'll experiment a bit later. The remote introspection is the reality for many OAutth2/OIDC applications so it does not constitute a risk in itself, the rate request limiting can also be enforced if required by the external tools, etc |
@sberyozkin Thanks, seems like this will work. |
@missourian55, @pedroigor I've spent some time on testing this workaround but since both the jwk refresh and introspection calls are totally async I could not block the introspection ones. |
Of course we are dealing with a somewhat academic case here, we expect the users do a proper HTTPS, even MTLS, but nonetheless, if we can optionally block the remote introspection then it would be a good option to have |
This issue will be revisited once we complete the migration to Vertx Web Client |
Hi @sberyozkin
You can see that one request fails where the fallback to token instrospection is used, which we do not want to use. I need to disable it in the config. So I did some tests with keycloak locally:
In our productive system we see 3-5 request fail every week. The only way to prevent this is to configure Edit:
|
Describe the bug
JWK keys are not refreshed
quarkus.oidc.token.forced-jwk-refresh-interval=10M
Expected behavior
JWK keys should be refreshed at the configured intervals by communicating with JWKS endpoint
Actual behavior
JWK keys are nor refreshed with this configuration
quarkus.oidc.token.forced-jwk-refresh-interval=10M
To Reproduce
quarkus.oidc.token.forced-jwk-refresh-interval=10M
Configuration
Screenshots
(If applicable, add screenshots to help explain your problem.)
Environment (please complete the following information):
uname -a
orver
: Linux x64 & Mac OSjava -version
: Java 11mvnw --version
orgradlew --version
): mvnwThe text was updated successfully, but these errors were encountered: