Last updated: September 2026
When Keycloak authenticates a user by sending their password to Kerberos without SPNEGO in the picture, it never asks the KDC for a service ticket it can decrypt with its own keytab. That means it cannot tell the real KDC from anything else that answers in its place. CVE-2026-95503, published 22 September 2026, is that missing check. An attacker positioned on an adjacent network can stand up a fake KDC, answer the authentication request, and get Keycloak to accept a login as any federated user.
Red Hat rates it CVSS 3.1 base 6.8, vector CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N, classified CWE-347, Improper Verification of Cryptographic Signature (GitHub Security Advisory GHSA-35j3-ccrv-pgvj, “A flaw was found in the Kerberos federation provider of Keycloak”, 2026). Two things make this one worth reading properly rather than filing under “patch it next cycle”: as of 23 September 2026 there is no released version carrying a fix, and whether you are exposed comes down to a single toggle in your federation provider rather than to your version number.
What does CVE-2026-95503 actually allow?
An attacker who can answer Kerberos traffic on the network segment between Keycloak and its KDC can authenticate as any user in the federated directory, without knowing that user’s password. The advisory describes the mechanism in one sentence: “When Kerberos password authentication is used without SPNEGO, the system fails to verify the identity of the Key Distribution Center (KDC) by requesting a server ticket.”
To see why that matters, it helps to separate the two things Kerberos is normally asked to prove. Getting a ticket-granting ticket proves that the user’s password decrypted something the KDC sent. Getting a service ticket for a principal whose key you hold locally proves that the thing you were talking to actually knows the shared secret in your keytab, because nothing else could have produced a ticket your keytab can open. The second step is what makes a KDC verifiable. Without that second step, a successful authentication only tells you that whatever answered the request accepted the credentials, not that it was your KDC.
The password path in the source
Keycloak’s Kerberos password authentication runs through KerberosUsernamePasswordAuthenticator, which builds a JAAS login context and calls login():
loginContext = new LoginContext("does-not-matter", null,
createJaasCallbackHandler(principal, password),
createJaasConfiguration());
loginContext.login();
The configuration that call uses comes from KerberosJdkProvider, and it is short enough to quote in full:
Map<String, Object> options = new HashMap<>();
options.put("storeKey", "true");
options.put("debug", String.valueOf(debug));
AppConfigurationEntry kerberosLMConfiguration = new AppConfigurationEntry(
"com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
That configuration carries two options, storeKey and debug, with no keytab, no service principal and no second round trip to verify anything. Krb5LoginModule obtains a TGT with the credentials it was handed and stops there, because that is all it was asked to do. A response from an impostor KDC, encrypted with a key the attacker chose, satisfies it.
The detail that turns this from an academic gap into a real bug is that the provider already holds everything the missing check needs. CommonKerberosConfig exposes both a server principal and a keytab:
public String getServerPrincipal() {
return getConfig().getFirst(KerberosConstants.SERVER_PRINCIPAL);
}
public String getKeyTab() {
return getConfig().getFirst(KerberosConstants.KEYTAB);
}
Those are configured on every Kerberos-enabled federation provider, and the SPNEGO path uses them. The password path does not consult them at all.
Why SPNEGO is not affected
SPNEGO inverts the direction of proof. The browser obtains a service ticket for Keycloak’s own principal from the KDC and presents it, and Keycloak decrypts that ticket with the key in its keytab. An impostor KDC cannot produce a ticket that opens with a key it does not have, so verification is a side effect of the protocol rather than an extra step somebody has to remember to code. That is the whole reason this CVE carries the phrase “without SPNEGO” in its description: desktop SSO through SPNEGO was never the exposed path.
| SPNEGO desktop SSO | Kerberos password authentication | |
|---|---|---|
| What Keycloak receives | A service ticket for its own principal | A username and password to check |
| What proves the KDC is real | Keycloak decrypts the ticket with its keytab | Nothing, on the affected path |
| Keytab and server principal used | Yes | No |
| Affected by CVE-2026-95503 | No | Yes |
Which Keycloak configurations are exposed?
Exposure follows one setting: whether your federation provider is allowed to check passwords against Kerberos at all. In the standalone Kerberos user federation provider, that is the allow-password-authentication property, registered in KerberosFederationProviderFactory as KerberosConstants.ALLOW_PASSWORD_AUTHENTICATION. In an LDAP provider with Kerberos integration switched on, it is use-kerberos-for-password-authentication, which routes password verification to Kerberos instead of an LDAP bind. Both are registered upstream with a default of false, so if either is on, somebody turned it on.
If that option is off, you are using SPNEGO only, and this CVE does not apply to you. If it is on, every password login through that provider takes the unverified path.
Then there is positioning, which is what holds the score down to 6.8. The vector says AV:A, adjacent network: the attacker needs a foothold on the same broadcast or routed segment where Keycloak’s Kerberos traffic lives, not an internet connection. AC:H says the attack complexity is high, because the attacker has to get Keycloak to talk to them rather than to the real KDC, which in practice means DNS or ARP manipulation, a rogue DHCP answer, or an on-path position that lets them beat the legitimate server. None of that is exotic on a flat corporate network, and a good deal of it is also the standard toolkit of anyone already inside one.
The impact half of that vector deserves attention even though the overall score reads as medium. It is C:H/I:H, meaning a successful attack is authentication bypass into arbitrary accounts. What holds the score at 6.8 is the difficulty of getting into position rather than any limit on the damage once an attacker is there.
How this differs from the LDAP CVEs you may have patched recently
This is not the LDAP certificate-validation problem, and it is not an LDAP bind issue. Those live in the TLS layer between Keycloak and the directory, and we covered that class in the LDAP certificate validation CVE writeup. CVE-2026-95503 is inside the Kerberos exchange itself, and it would still be present on a network where every LDAP connection is properly TLS-verified. If you run Keycloak against Active Directory with Kerberos enabled, the two need separate checks.
Is there a fixed version yet?
No. As of 23 September 2026, the day after publication, the advisory lists no patched version, and no released Keycloak build carries a fix. We checked three things rather than assuming.
The newest published community release is 26.7.4, tagged 16 September 2026, which predates the CVE by six days. Upstream tags stop there: there is no 26.7.5 and no 26.8.0, despite 26.8.0 appearing in issue trackers as a future target. And on the main branch today, createJaasConfigurationForUsernamePasswordLogin still builds the two-option JAAS configuration quoted above, with no keytab and no service-ticket step. The most recent change to the Kerberos federation module is an August 2026 commit returning the SPNEGO mutual authentication token, which touches the path that was already safe.
So the remediation right now is configuration, not a version bump. That is less satisfying than a version number to upgrade to, and it is what the evidence supports.
When a fix does land, expect it on more than the newest line. Keycloak does keep publishing point releases on older minor branches: 26.4.15 and 26.6.6 both shipped on 11 August 2026, after 26.7.0 was already out in July, and 26.4.16 and 26.6.7 followed on 7 September 2026, each carrying its own backported security fixes. For the avoidance of doubt, we checked those September tags too, and they ship the same unverified password path. Check the newest tag on the line you actually run before scheduling a minor-version upgrade you may not need. Our Keycloak 26.7.3 patch checklist works through that reasoning on a release where several fixes landed at once.
How do you harden this today?
Four moves, in the order we would do them.
Turn off Kerberos password authentication where nothing uses it. Plenty of deployments enable it while setting up desktop SSO and never rely on it, because real logins arrive through SPNEGO and the password toggle is left on as a fallback nobody tested. Switching it off removes the vulnerable path completely. Check your realm’s authentication flows and event logs first: if you see Kerberos-based logins that did not come from SPNEGO, something is using it.
Where you do need it, constrain KDC discovery. The attack depends on Keycloak being persuaded to talk to the wrong KDC. Pinning KDC hosts explicitly in krb5.conf rather than relying on DNS SRV discovery removes the easiest way to redirect that traffic, and putting the KDC on a segment your general user population cannot reach removes the adjacency the vector requires. Neither is a fix. Both raise the bar meaningfully against an attacker who has to win a race from inside your network.
Watch the login events. Be precise about what this can and cannot show you. The attack sits between Keycloak and the KDC, so there is no tell-tale mark on the user side of the login, and Keycloak has no event field that says which KDC answered. What you can watch is the surrounding shape: Kerberos login outcomes changing character without a corresponding change you made, a burst of failures followed by successes, or Kerberos activity that does not line up with your KDC’s own logs. Correlating Keycloak’s login events against the KDC’s own authentication records is the check that actually catches a second KDC answering, and it only works if the events leave the cluster, which is the argument for forwarding Keycloak events to your SIEM before you need them rather than after.
Re-test AD SSO in staging when the patch arrives. Whatever shape the upstream fix takes, requiring a service ticket means requiring a working keytab and server principal on a code path that previously ignored both. A deployment with a stale or misconfigured keytab has been getting away with it on the password path and will stop getting away with it. Finding that in staging costs you an afternoon of keytab work, and finding it in production costs you every Kerberos login at once. The rest of our Keycloak hardening checklist is worth a pass at the same time.
What changes when somebody else runs your Keycloak?
The split is worth being precise about, because it is easy to oversell. Skycloak is identity management as a service built on upstream Keycloak, so the behaviour described in this post is upstream behaviour, not a fork with a private patch. What a managed provider carries is the part most teams are actually short on: tracking advisories like this one the day they publish, sequencing the patch onto your line when it exists, and running the upgrade with a staging pass that catches the keytab problem described above.
What stays yours is realm configuration, and this CVE lives in realm configuration. Nobody else can decide whether your federation provider should accept Kerberos passwords, because only you know which of your applications depends on it. The same split applies to every identity provider and directory you federate: the platform is run for you, the trust decisions are not. The useful division is that your provider should be the reason you hear about a Kerberos CVE within a day, and you should be the one who answers whether that toggle needs to be on. If your Kerberos setup came from an Active Directory integration that somebody configured years ago and nobody has revisited, that answer is worth finding out this week rather than at the next audit.
FAQ
Am I affected if I only use SPNEGO desktop SSO?
No. The flaw is specific to Kerberos password authentication. SPNEGO has the browser present a service ticket that Keycloak decrypts with its own keytab, which verifies the KDC as a property of the exchange. Confirm the password-authentication toggle on your federation provider is actually off rather than assuming it. Upstream registers both the Kerberos provider’s allow-password-authentication and the LDAP provider’s use-kerberos-for-password-authentication with a default of false, so an enabled one was switched on by somebody, usually while getting desktop SSO working.
Which Keycloak versions are affected?
The advisory does not list version ranges, and no released build carries a fix as of 23 September 2026. The unverified password path is present on main today and is not new code, so treat every 26.x deployment using Kerberos password authentication as affected until upstream says otherwise.
Does CVSS 6.8 mean I can wait for the next quarterly upgrade?
The score is moderate because the attacker needs adjacent-network position and has to win a race to answer as the KDC. The consequence, if they manage it, is authentication bypass into any federated account, rated C:H/I:H. On a flat internal network where a compromised workstation is adjacent to everything, the mitigating factor is thinner than the number suggests.
What about LDAP-only federation without Kerberos?
Not affected. This CVE lives in the Kerberos exchange. An LDAP provider that verifies passwords with an LDAP bind never enters the vulnerable code. Our LDAP user federation explainer covers which path your provider is actually taking, which is not always what the original configurer intended.
Will patching break our Active Directory logins?
It might, and that is the one thing to plan for. A fix that requires a server ticket requires a valid keytab and server principal on a path that previously ignored them, so any deployment carrying a stale keytab will surface it at upgrade time. Test Kerberos logins in staging against the patched build before production.
Sources
- GitHub Security Advisory, “GHSA-35j3-ccrv-pgvj: A flaw was found in the Kerberos federation provider of Keycloak,” published 22 September 2026, retrieved 2026-09-23, https://github.com/advisories/GHSA-35j3-ccrv-pgvj
- Keycloak source,
KerberosUsernamePasswordAuthenticator.java,mainbranch, retrieved 2026-09-23, https://github.com/keycloak/keycloak/blob/main/federation/kerberos/src/main/java/org/keycloak/federation/kerberos/impl/KerberosUsernamePasswordAuthenticator.java - Keycloak source,
KerberosJdkProvider.java,mainbranch, retrieved 2026-09-23, https://github.com/keycloak/keycloak/blob/main/common/src/main/java/org/keycloak/common/util/KerberosJdkProvider.java - Keycloak source,
CommonKerberosConfig.javaandKerberosFederationProviderFactory.java,mainbranch, retrieved 2026-09-23, https://github.com/keycloak/keycloak/tree/main/federation/kerberos/src/main/java/org/keycloak/federation/kerberos - Oracle, “Krb5LoginModule class documentation,” Java SE API reference, retrieved 2026-09-23, https://docs.oracle.com/en/java/javase/21/docs/api/jdk.security.auth/com/sun/security/auth/module/Krb5LoginModule.html
- IETF, “The Kerberos Network Authentication Service (V5)” (RFC 4120), retrieved 2026-09-23, https://datatracker.ietf.org/doc/html/rfc4120