Skip to main content
Vulnerability Database/CVE-2026-93999

CVE-2026-93999: Keycloak OIDC Auth Bypass Vulnerability

CVE-2026-93999 is an authentication bypass flaw in Keycloak OIDC that allows refresh tokens to obtain access tokens for disabled clients. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-93999 Overview

CVE-2026-93999 is an authorization flaw in the OpenID Connect (OIDC) protocol implementation of Keycloak, Red Hat's open-source identity and access management (IAM) solution. During the token refresh process, Keycloak restores requested audiences from stored client IDs but fails to verify whether the target audience client remains enabled. An application holding a valid refresh token can continue obtaining new access tokens for a disabled client. This bypasses administrative access controls for resource servers that rely on offline JSON Web Token (JWT) validation. The weakness is categorized under CWE-862: Missing Authorization.

Critical Impact

Attackers with a valid refresh token can bypass client disablement and continue accessing resource servers that validate JWTs offline.

Affected Products

  • Red Hat Keycloak (OIDC protocol implementation)
  • Red Hat build of Keycloak
  • Downstream identity products relying on affected Keycloak versions

Discovery Timeline

  • 2026-09-19 - CVE-2026-93999 published to the National Vulnerability Database (NVD)
  • 2026-09-22 - Last updated in NVD database

Technical Details for CVE-2026-93999

Vulnerability Analysis

The flaw resides in Keycloak's OIDC token refresh workflow. When a client submits a refresh token, the server reconstructs the requested audiences from stored client identifiers linked to the original grant. The server issues a fresh access token containing those audiences without re-validating whether each audience client is still enabled in the realm configuration. Administrators frequently disable a client to revoke its access without deleting the client record. Because the enablement state is not checked at refresh time, the revocation is not enforced for holders of previously issued refresh tokens.

Resource servers that perform local JWT signature and claim validation, rather than calling the token introspection endpoint, will accept these tokens as valid. This produces a persistent access window that persists until the refresh token itself expires or is explicitly revoked.

Root Cause

The root cause is a missing authorization check ([CWE-862]) in the refresh grant handler. The code path that rebuilds token audiences from persisted client IDs does not consult the enabled flag of the target client entity before minting a new access token bound to that audience.

Attack Vector

Exploitation requires an attacker or third-party application already in possession of a valid refresh token issued before the target audience client was disabled. The attacker submits a standard grant_type=refresh_token request to Keycloak's token endpoint. Keycloak returns a new access token asserting the disabled client as an audience. The attacker then presents the token to any resource server that trusts the Keycloak issuer and validates JWTs offline. The vulnerability requires low privileges and high attack complexity, and it does not affect availability.

No public proof-of-concept exploit is available. See the Red Hat CVE-2026-93999 Advisory and Red Hat Bug Report #2537165 for vendor technical detail.

Detection Methods for CVE-2026-93999

Indicators of Compromise

  • Access tokens issued via refresh_token grant that contain an aud claim referencing a client whose enabled attribute is set to false in the Keycloak admin console.
  • Successful authentication events at resource servers using JWTs whose audience client has been administratively disabled.
  • Repeated refresh token exchanges from a single session after a client was disabled in the realm.

Detection Strategies

  • Correlate Keycloak REFRESH_TOKEN events with the current client enablement state and alert when audiences map to disabled clients.
  • Enable Keycloak event logging and forward TOKEN_EXCHANGE and REFRESH_TOKEN events to a centralized log platform for query.
  • At resource servers, log the full aud claim of every accepted JWT and cross-reference against the authoritative list of enabled clients.

Monitoring Recommendations

  • Ingest Keycloak admin and authentication event streams into a security data lake with OIDC field normalization.
  • Build a scheduled query that lists all access tokens issued in the past 24 hours whose audience clients are currently disabled.
  • Alert on any use of long-lived offline tokens that reference clients modified in the last 30 days.

How to Mitigate CVE-2026-93999

Immediate Actions Required

  • Apply the Keycloak security update referenced in the Red Hat CVE-2026-93999 Advisory as soon as a fixed build is available for your distribution.
  • Revoke active refresh tokens and offline sessions for any client that has been disabled but not yet deleted.
  • Audit realms for disabled clients that still have active sessions and terminate those sessions from the admin console.

Patch Information

Red Hat tracks remediation under Bug #2537165. Consult the Red Hat CVE-2026-93999 Advisory for the fixed component versions and errata identifiers for each supported Keycloak and Red Hat build of Keycloak release stream.

Workarounds

  • Configure resource servers to call Keycloak's token introspection endpoint (/protocol/openid-connect/token/introspect) instead of validating JWTs offline, so client enablement is checked on each request.
  • Delete rather than disable clients when access must be permanently revoked, and rotate any client secrets tied to those clients.
  • Reduce refresh token and offline session lifetimes in the realm token settings to shrink the exposure window.
  • Restrict use of the offline access scope to trusted clients only.
bash
# Force resource servers to introspect tokens rather than validate offline
# Example for a Spring Boot resource server (application.yml)
spring:
  security:
    oauth2:
      resourceserver:
        opaquetoken:
          introspection-uri: https://keycloak.example.com/realms/prod/protocol/openid-connect/token/introspect
          client-id: resource-server
          client-secret: <redacted>

# Revoke active sessions for a disabled client via kcadm.sh
kcadm.sh update clients/<client-uuid>/logout-all -r prod

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.