The vulnerability lies in Keycloak's failure to verify if an Identity Provider (IdP) is enabled before processing authentication or authorization requests based on JWTs issued by that IdP. An administrator might disable an IdP due to a compromise, but without this check, Keycloak would still trust tokens signed by the compromised IdP's key.
The analysis of the security patch 176dc8902ce552056d3648c4601d519afc6fb043 reveals two key locations where this check was missing:
-
org.keycloak.authentication.authenticators.client.FederatedJWTClientAuthenticator.authenticateClient: This method is responsible for authenticating clients using JWTs from a federated IdP. The patch adds a check, !lookup.identityProviderModel().isEnabled(), to ensure the IdP is active before proceeding. The absence of this check meant that a client could be authenticated using a token from a disabled IdP.
-
org.keycloak.protocol.oidc.grants.JWTAuthorizationGrantType.process: This method handles the JWT authorization grant flow. The patch introduces a check, !identityProviderModel.isEnabled(), and throws an exception if the IdP is disabled. Previously, this method would process grant requests and issue access tokens even if the originating IdP was disabled, as long as the JWT was correctly signed.
These two functions are the entry points where a malicious JWT from a disabled IdP would be processed. During an exploit, a runtime profile would show calls to these functions as they validate the malicious token and incorrectly grant access. The fix in both cases was to add an explicit check for the isEnabled status of the Identity Provider.