CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-1486
8.80.04%

Zombie IdPs: The Keycloak CVE-2026-1486 Deep Dive

Alon Barad
Alon Barad
Software Engineer

Feb 10, 2026·4 min read·34 visits

PoC Available

Executive Summary (TL;DR)

Keycloak fails to check if an Identity Provider is disabled before accepting its JWTs. If an admin disables a compromised IdP but doesn't delete its keys, the attacker can still login. CVSS 8.8.

A critical logic flaw in Keycloak's implementation of JWT Authorization Grants allows disabled Identity Providers (IdPs) to continue issuing valid access tokens. By failing to check the 'enabled' status of an IdP during the resolution process, Keycloak permits attackers possessing a disabled provider's signing keys to bypass administrative restrictions and maintain unauthorized access.

The Hook: When 'Off' Doesn't Mean 'Off'

Identity and Access Management (IAM) is the bouncer of your digital club. You trust it to know who's on the list and who's banned. In Keycloak, the 'Identity Provider' (IdP) toggle is supposed to be the ultimate kill switch. You suspect a partner is compromised? You flip the switch to Disabled. You go home. You sleep tight.

But in CVE-2026-1486, that switch is a lie. It’s like locking your front door but leaving the key under the mat—and telling the burglar where the mat is. This vulnerability reveals a disconnect between the administrative intent (UI configuration) and the runtime logic (token issuance). It turns out, Keycloak was perfectly happy to mint fresh access tokens for Identity Providers that were explicitly told to go away, provided they still had the right cryptographic handshake.

The Flaw: A Logic Gap in RFC 7523

The vulnerability resides in how Keycloak handles the JWT Profile for OAuth 2.0 Client Authentication and Authorization Grants (RFC 7523). When Keycloak receives a JWT assertion, it needs to figure out who signed it. It looks at the iss (issuer) claim in the token and matches it against its configured Identity Providers.

Here is the logic flow in the vulnerable versions:

  1. Receive JWT.
  2. Extract iss claim.
  3. Look up the IdentityProviderModel that matches this alias/issuer.
  4. (MISSING STEP) Check if IdentityProviderModel.isEnabled() is true.
  5. Validate the JWT signature using the stored public keys for that model.
  6. Issue a local access token.

The code was so focused on cryptographic verification—"Does this signature match the public key we have on file?"—that it forgot the administrative verification—"Are we even supposed to be talking to this guy?" This is a classic case of valid crypto lulling developers into a false sense of security.

The Code: The Smoking Gun

The fix is embarrassingly simple, which highlights just how critical the oversight was. The patch was applied primarily in FederatedJWTClientAuthenticator.java and JWTAuthorizationGrantType.java.

Let's look at the diff in FederatedJWTClientAuthenticator.java (commit 176dc89):

// THE VULNERABLE CODE
if (lookup == null || lookup.identityProviderModel() == null || lookup.clientModel() == null) {
    // Error handling
}
 
// THE PATCHED CODE
if (lookup == null || 
    lookup.identityProviderModel() == null || 
    !lookup.identityProviderModel().isEnabled() || // <--- The Savior
    lookup.clientModel() == null) {
    // Error handling
}

And similarly in JWTAuthorizationGrantType.java:

// Added explicitly before signature validation
if (!identityProviderModel.isEnabled()) {
    throw new RuntimeException("Identity Provider is not enabled");
}

Without these lines, the code retrieved the configuration, saw the public keys were valid, and proceeded to grant access. The isEnabled() flag was effectively a UI decoration with no backend enforcement during this specific grant flow.

The Exploit: The Ex-Partner Scenario

Let's construct a realistic attack scenario. Imagine you are a SaaS provider using Keycloak. You have a B2B integration with ShadyCorp, set up as an Identity Provider. You give them a client_id and import their public keys so they can mint tokens for their users to access your API.

Day 1: You read news that ShadyCorp got hacked. Their private signing keys are in the wild.

Day 2: You rush to your Keycloak Admin Console. You find the ShadyCorp Identity Provider. You toggle Enabled to OFF. You breathe a sigh of relief. You assume the threat is neutralized.

Day 3: The attacker, holding ShadyCorp's private key, crafts a JWT:

{
  "iss": "shady-corp-alias",
  "sub": "admin-user",
  "aud": "your-keycloak-realm",
  "exp": 1770000000
}

They sign this JWT with the stolen private key. They send it to your Keycloak token endpoint:

POST /realms/{realm}/protocol/openid-connect/token grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer assertion={signed_jwt}

The Result: Keycloak looks up shady-corp-alias. It finds the config. It sees the public key. It verifies the signature. It ignores the fact that you disabled it. It issues a shiny new access token with full privileges. The attacker is in.

The Fix: Killing the Zombie

The primary fix is obviously to upgrade Keycloak. The patched versions (Red Hat build 26.4.9-1, 26.4-11, etc.) introduce the boolean checks ensuring isEnabled() is respected.

However, if you are stuck on a legacy version and cannot upgrade immediately, you must understand that disabling the provider is insufficient. To mitigate this without a patch, you must perform a 'cryptographic lobotomy':

  1. Open the Identity Provider configuration.
  2. Delete the stored public keys/certificates associated with that provider.
  3. Or, simply delete the Identity Provider configuration entirely.

If Keycloak cannot verify the signature (because the key is gone), the exploit fails, regardless of the logic bug.

Official Patches

Red HatRed Hat Security Advisory and Patch Info
KeycloakUpstream Pull Request #46148

Fix Analysis (1)

Technical Appendix

CVSS Score
8.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.04%
Top 86% most exploited

Affected Systems

Keycloak (Upstream Project)Red Hat build of Keycloak

Affected Versions Detail

Product
Affected Versions
Fixed Version
Red Hat build of Keycloak
Red Hat
26.4.x < 26.4.926.4.9-1
Keycloak
Keycloak
< Commit 176dc89PR #46148
AttributeDetail
CWECWE-287
CVSS v3.18.8 (High)
Attack VectorNetwork
EPSS Score0.00045
ImpactAuthorization Bypass
Exploit StatusPoC Available (Logic Trivial)
Patch StatusAvailable

MITRE ATT&CK Mapping

T1078Valid Accounts
Defense Evasion
T1550Use Alternate Authentication Material
Defense Evasion
T1098Account Manipulation
Persistence
CWE-287
Improper Authentication

Known Exploits & Detection

N/ALogic flaw exploitable by any valid JWT signed by a disabled provider key.

Vulnerability Timeline

Vulnerability reported to Red Hat
2026-01-27
CVE-2026-1486 Published
2026-02-09
Patch released (Commit 176dc89)
2026-02-10

References & Sources

  • [1]Red Hat Bugzilla #2433347
  • [2]Red Hat CVE Database

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.