CVE-2026-97176: Keycloak Step-Up Authentication Bypass

Guilliano Molaire Guilliano Molaire 9 min read

Last updated: September 2026

CVE-2026-97176 is a Keycloak flaw in step-up authentication: when a client demands a higher level of authentication as an essential acr claim, and the user already has a single sign-on session at a lower level, Keycloak can issue the token at the lower level instead of forcing the step-up. The browser flow’s Cookie authenticator is the path named in the advisory title. Red Hat published it on 24 September 2026 with a CVSS 3.1 base score of 4.2, and no fixed Keycloak release exists yet.

The fastest protection does not depend on the fix. If your application checks the acr claim in the ID token before it allows the sensitive action, a token issued at the wrong level is refused by the application even when Keycloak lets it through. Keycloak’s own documentation already recommends that check.

What does CVE-2026-97176 break?

It breaks the guarantee behind essential acr requests. Keycloak’s server administration guide states that when a login request asks for acr as an essential claim, Keycloak “will always return one of the specified levels,” and throws an error if it cannot. In the CVE record Red Hat published on 24 September 2026, the flaw is described as a logic error in how session re-evaluations are handled, so that Keycloak “may incorrectly issue a token at the lower security level instead of enforcing the required higher level” (CVE Program, CVE-2026-97176 record, 2026).

Essential acr versus an ordinary acr_values request

Step-up authentication means asking a signed-in user for a stronger factor before a sensitive action, such as a payment or a change to account security. In Keycloak you model it with levels of authentication (LoA): subflows in the browser flow guarded by the Condition – Level of Authentication authenticator, where level 1 might be a password and level 2 adds OTP or a passkey. Our Keycloak step-up authentication guide walks through that setup.

A client can request a level two ways, and the difference matters for this CVE. The acr_values parameter requests a level as a preference, which Keycloak tries to satisfy. The OIDC claims parameter can mark acr as essential, for example {"id_token":{"acr":{"essential":true,"values":["gold"]}}}. OpenID Connect Core 1.0 says that for an essential acr, the authorization server must return one of the requested values or treat the attempt as a failed authentication. In AuthorizationEndpoint, Keycloak records an essential request by setting a force-level-of-authentication note on the authentication session.

In the current Keycloak source, two pieces of code share the job, and the advisory title points at the first of them.

The Cookie authenticator runs first in the default browser flow. When it finds an existing SSO session, it reads the highest level that session still holds. If the client is asking for more, it sets the current level to what the session already has and returns “attempted”, so the flow carries on to the step-up subflows. If the session already satisfies the request, it attaches the session and succeeds without asking the user for anything.

The check that enforces an essential request lives elsewhere. ConditionalLoaAuthenticator.onTopFlowSuccess, a callback that runs when the whole browser flow finishes, compares the level achieved with the level requested and fails the login with “Forced level of authentication did not meet the requirements” when an essential request was not met.

Red Hat’s title, “essential acr requirement silently bypassed via cookie authenticator”, places the failure on the path where an existing session is re-evaluated and the flow completes without the higher level. The fix has not been published, so we cannot point to the exact line, and we have not reproduced the bug. What matters for defenders is the outcome the record describes: a token at a lower level than the essential request demanded, with no error.

Which Keycloak deployments are exposed?

You are exposed if an application relies on Keycloak to enforce an essential acr for step-up, without checking the returned acr itself. Red Hat’s vector is CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N, classified CWE-862 Missing Authorization. Low privileges required means the attacker is a user who can already sign in at the lower level, and high attack complexity reflects the specific session state needed.

Clients that send an essential acr. The trigger is a claims parameter marking acr as essential, sent to a realm whose browser flow uses Condition – Level of Authentication subflows. Clients that only send acr_values never asked Keycloak to fail hard, so a lower level from them is expected behaviour rather than this bug, and those clients should already be checking acr.

Users who already have a lower-level session. The scenario starts with a user signed in at, say, level 1 through SSO, followed by a request for level 2 from the same browser. A fresh login with no session does not go down the cookie re-evaluation path.

Applications that trust the redirect without reading acr. If your application receives the authorization code, gets tokens and then allows the high-risk action purely because the login round trip succeeded, it has delegated the whole decision to Keycloak. That is the configuration this CVE turns into a bypass.

SAML clients deserve a look too. SamlService sets the same force-level note whenever it resolves a level for a SAML request, either from the service provider’s RequestedAuthnContext or from the client’s minimum ACR setting. The CVE record does not mention SAML, so treat that as a reason to test rather than as a confirmed exposure.

What should I do before a fix ships?

Have every application that relies on step-up verify the acr claim, and force full re-authentication for the most sensitive actions. As of 25 September 2026, the CVE record names no fixed version, Red Hat states that no mitigation meets its criteria, and the newest community releases on each maintained line (26.7.4, 26.6.7 and 26.4.16) predate the disclosure.

Check acr in the application. Keycloak adds the acr claim through the acr loa level protocol mapper in the built-in acr client scope, which is a realm default scope for new clients. Keycloak’s guide already warns that claims and acr_values can be modified in the browser and tells clients to double-check acr in the ID token. Read it, compare it with the level you requested, and refuse the action if it is lower. Resource servers can apply the same check to the access token, and our backend token verification guide shows where that check fits.

Force re-authentication for the actions that matter most. Sending prompt=login or max_age=0 with the step-up request makes the Cookie authenticator treat the request as a full re-authentication: it resets the level to none and does not reuse levels from the earlier session. The user re-enters every factor, including the password, which is more friction. In our reading of the code this takes the cookie re-evaluation out of the picture, but since the fix is not published, treat it as defence in depth behind the acr check rather than a proven way around the bug.

Protect the request parameters. Pushed authorization requests (PAR) or signed request objects stop a user from editing claims in the URL. They do not fix this CVE, but they close the related gap the Keycloak documentation warns about, and together with the acr check they make the level decision tamper-resistant from both sides.

Log the level you got. Recording the acr of every step-up token next to the action it authorized gives you evidence if you later need to find actions approved at the wrong level.

When the fix lands, expect it on more than the newest minor line: the 11 August 2026 releases of 26.4.15 and 26.6.6 came out after 26.7.0, which shows Keycloak patches older lines too. Watch the release notes for your own line. If you run the Red Hat build of Keycloak, follow Red Hat’s advisory for the product version that carries the fix. For sequencing the upgrade itself, see our Keycloak cluster upgrade strategy.

Why is a 4.2 CVSS score still worth acting on?

The base score is modest because the attacker needs a valid account and the right session state, but the impact lands on the one control step-up exists to provide. The confidentiality and integrity impacts are rated Low in general terms, while for a bank or a SaaS admin console the “lower level” might be the difference between a password and a password plus a passkey on a payment approval.

The broader point is about where an assurance decision should live. A step-up flow has two parties, the identity provider that authenticates and the application that authorizes the action, and CVE-2026-97176 shows why both should check. An application that reads acr costs nothing extra when Keycloak behaves correctly, and it still refuses the action when Keycloak does not. We treat “the relying party verifies acr” as part of the step-up design, not an optional extra, which is also where Keycloak’s own documentation lands.

If your step-up factor is a passkey, our passkeys and WebAuthn guide covers configuring it as the level 2 method, and our post on MFA fatigue and helpdesk vishing covers the social engineering attacks that target the same flows.

What does managed Keycloak change here?

A managed service takes the upgrade off your plate, while the way your applications consume acr stays in your code. On Skycloak, identity management as a service built on upstream Keycloak, we roll security releases onto customer clusters, so the fix for CVE-2026-97176 arrives without you scheduling an upgrade. Checking acr in your applications, and deciding which actions warrant prompt=login, are design choices that stay with you, and they hold whoever runs the server. Our Keycloak security audit and hardening checklist covers the rest of the authentication settings worth reviewing alongside this one.

Frequently asked questions

What is an essential acr claim?

It is a request, made through the OpenID Connect claims parameter, that marks the acr (authentication context class reference) claim as mandatory with a list of acceptable values. Under OpenID Connect Core 1.0, the server must return one of those values or fail the authentication. Keycloak maps acr values to its numeric levels of authentication.

Which Keycloak versions are affected by CVE-2026-97176?

The CVE record published on 24 September 2026 lists the Red Hat build of Keycloak without version ranges and Red Hat Single Sign-On 7 as unaffected. No community release carrying a fix existed as of 25 September 2026, when 26.7.4 was the newest release. Test your own step-up flows rather than inferring from a version number.

Does checking acr in my application fully protect me?

It protects the action your application gates. If the ID token’s acr is lower than what you requested and your application refuses to proceed, a token issued at the wrong level cannot authorize the sensitive step. Other applications that trust the same session without checking acr still need the same change.

Does this affect clients that only use acr_values?

Not in the way the CVE describes. acr_values requests a level without making it mandatory, so Keycloak is allowed to return a lower level and the client is expected to check. The CVE concerns essential requests, where Keycloak is supposed to fail rather than downgrade.

Who reported CVE-2026-97176?

The CVE record credits Amaury Cormier (GitHub: Mandrak-Kimigo) for reporting the issue to Red Hat. It was reported and made public on 23 September 2026 and published as a CVE record on 24 September 2026, tracked as Red Hat Bugzilla 2539964.

Sources

  • CVE Program, “CVE-2026-97176: essential acr requirement silently bypassed via cookie authenticator”, CNA record from Red Hat, published 24 September 2026, retrieved 2026-09-25, https://www.cve.org/CVERecord?id=CVE-2026-97176 (record JSON: https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/97xxx/CVE-2026-97176.json)
  • Red Hat Customer Portal, “CVE-2026-97176”, https://access.redhat.com/security/cve/CVE-2026-97176 (linked from the CVE record; not reachable from our research environment)
  • Red Hat Bugzilla, bug 2539964, https://bugzilla.redhat.com/show_bug.cgi?id=2539964
  • Keycloak Server Administration Guide source, “Creating a browser login flow with step-up mechanism”, flows.adoc, keycloak/keycloak on GitHub, retrieved 2026-09-25, https://github.com/keycloak/keycloak/blob/main/docs/documentation/server_admin/topics/authentication/flows.adoc
  • OpenID Foundation, “OpenID Connect Core 1.0”, section 5.5.1.1 on requesting the acr claim, https://openid.net/specs/openid-connect-core-1_0.html
  • Keycloak, CookieAuthenticator.java, keycloak/keycloak on GitHub, retrieved 2026-09-25, https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/authentication/authenticators/browser/CookieAuthenticator.java
  • Keycloak, ConditionalLoaAuthenticator.java, keycloak/keycloak on GitHub, retrieved 2026-09-25, https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/authentication/authenticators/conditional/ConditionalLoaAuthenticator.java
  • Keycloak, AuthorizationEndpoint.java, keycloak/keycloak on GitHub, retrieved 2026-09-25, https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java
  • Keycloak releases, tags 26.7.4, 26.6.7 and 26.4.16, retrieved 2026-09-25, https://github.com/keycloak/keycloak/releases

Patched on the day, not on your next maintenance window

Keycloak 26.7.2 fixed CVE-2026-18963, an account takeover through password reset. Skycloak had it available for auto-upgrade and told customers the same day upstream shipped it. Self-hosted teams schedule that work themselves.

Guilliano Molaire
Written by
Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Start Free Trial Talk to Sales
© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman