CVE-2026-1486
Description
A flaw was found in Keycloak. A vulnerability exists in the jwt-authorization-grant flow where the server fails to verify if an Identity Provider (IdP) is enabled before issuing tokens. The issuer lookup mechanism (lookupIdentityProviderFromIssuer) retrieves the IdP configuration but does not filter for isEnabled=false. If an administrator disables an IdP (e.g., due to a compromise or offboarding), an entity possessing that IdP's signing key can still generate valid JWT assertions that Keycloak accepts, resulting in the issuance of valid access tokens.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.keycloak:keycloak-servicesMaven | >= 26.5.0, < 26.5.3 | 26.5.3 |
org.keycloak:keycloak-servicesMaven | < 26.4.9 | 26.4.9 |
Patches
2176dc8902ce5Check if idp is enabled for JWT Auth Grant and Federated Client Auth (#46148)
4 files changed · +27 −1
services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java+1 −1 modified@@ -97,7 +97,7 @@ public void authenticateClient(ClientAuthenticationFlowContext context) { } ClientAssertionIdentityProviderFactory.LookupResult lookup = strategy.lookup(context); - if (lookup == null || lookup.identityProviderModel() == null || lookup.clientModel() == null) { + if (lookup == null || lookup.identityProviderModel() == null || !lookup.identityProviderModel().isEnabled() || lookup.clientModel() == null) { return; }
services/src/main/java/org/keycloak/protocol/oidc/grants/JWTAuthorizationGrantType.java+4 −0 modified@@ -77,6 +77,10 @@ public Response process(Context context) { } event.detail(Details.IDENTITY_PROVIDER, identityProviderModel.getAlias()); + if (!identityProviderModel.isEnabled()) { + throw new RuntimeException("Identity Provider is not enabled"); + } + if(!OIDCAdvancedConfigWrapper.fromClientModel(context.getClient()).getJWTAuthorizationGrantAllowedIdentityProviders().contains(identityProviderModel.getAlias())) { throw new RuntimeException("Identity Provider is not allowed for the client"); }
tests/base/src/test/java/org/keycloak/tests/client/authentication/external/BaseClientAuthTest.java+11 −0 modified@@ -117,6 +117,17 @@ public void testClientIdAllowedAsAudience() { assertFailure(INTERNAL_CLIENT_ID, TOKEN_ISSUER, EXTERNAL_CLIENT_ID, jwt.getId(), events.poll()); } + @Test + public void testDisabledIdentityProvider() { + realm.updateIdentityProvider(IDP_ALIAS, rep -> { + rep.setEnabled(false); + }); + + JsonWebToken jwt = createDefaultToken(); + assertFailure(doClientGrant(jwt)); + assertFailure(null, TOKEN_ISSUER, EXTERNAL_CLIENT_ID, jwt.getId(), "client_not_found", events.poll()); + } + @Override protected OAuthIdentityProvider getIdentityProvider() { return identityProvider;
tests/base/src/test/java/org/keycloak/tests/oauth/AbstractJWTAuthorizationGrantTest.java+11 −0 modified@@ -298,4 +298,15 @@ public void testSuccessGrant() { AccessTokenResponse response = oAuthClient.jwtAuthorizationGrantRequest(jwt).send(); assertSuccess("test-app", response); } + + @Test + public void testDisabledIdentityProvider() { + realm.updateIdentityProvider(IDP_ALIAS, rep -> { + rep.setEnabled(false); + }); + + String jwt = getIdentityProvider().encodeToken(createDefaultAuthorizationGrantToken()); + AccessTokenResponse response = oAuthClient.jwtAuthorizationGrantRequest(jwt).send(); + assertFailure("Identity Provider is not enabled", response, events.poll()); + } }
8316e8538f00Check if the idp is enabled for Federated Client Authentication
2 files changed · +12 −1
services/src/main/java/org/keycloak/authentication/authenticators/client/FederatedJWTClientAuthenticator.java+1 −1 modified@@ -89,7 +89,7 @@ public void authenticateClient(ClientAuthenticationFlowContext context) { } private ClientAssertionIdentityProvider getClientAssertionIdentityProvider(KeycloakSession session, IdentityProviderModel identityProviderModel) { - if (identityProviderModel == null) { + if (identityProviderModel == null || !identityProviderModel.isEnabled()) { return null; } IdentityProvider<?> identityProvider = IdentityBrokerService.getIdentityProvider(session, identityProviderModel);
tests/base/src/test/java/org/keycloak/tests/client/authentication/external/BaseClientAuthTest.java+11 −0 modified@@ -95,6 +95,17 @@ public void testClientAssertionsNotSupported() { assertFailure(null, TOKEN_ISSUER, EXTERNAL_CLIENT_ID, jwt.getId(), "client_not_found", events.poll()); } + @Test + public void testDisabledIdentityProvider() { + realm.updateIdentityProviderWithCleanup(IDP_ALIAS, rep -> { + rep.setEnabled(false); + }); + + JsonWebToken jwt = createDefaultToken(); + assertFailure(doClientGrant(jwt)); + assertFailure(null, TOKEN_ISSUER, EXTERNAL_CLIENT_ID, jwt.getId(), "client_not_found", events.poll()); + } + @Override protected OAuthIdentityProvider getIdentityProvider() { return identityProvider;
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-37gf-gmxv-74wvghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-1486ghsaADVISORY
- access.redhat.com/errata/RHSA-2026:2365nvdWEB
- access.redhat.com/errata/RHSA-2026:2366nvdWEB
- access.redhat.com/security/cve/CVE-2026-1486nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/keycloak/keycloak/commit/176dc8902ce552056d3648c4601d519afc6fb043ghsaWEB
- github.com/keycloak/keycloak/commit/8316e8538f0037d9f998181e73122cff93a94035ghsaWEB
- github.com/keycloak/keycloak/issues/46146ghsaWEB
- github.com/keycloak/keycloak/pull/46148ghsaWEB
News mentions
0No linked articles in our index yet.