☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]
Keycloak logo [ WEBSITE ] [ VENDOR STATS ]
CVSS: 4.2 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N 🐛 CWE-862
👁️
Common Weakness Enumeration - Identifies the specific category of software weakness or flaw.

CVE-2026-93999

CVE-2026-93999 Vulnerability in Keycloak
📅 PUBLISHED: 2026-09-19 00:00 UTC 🔄 UPDATED: 2026-09-22 09:08 UTC
[ ZERO-DAY / UNPATCHED ] [ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🥷 MITRE: T1078
👁️
MITRE ATT&CK Tactic - Describes the strategy hackers use to execute this attack.
Country: Global License: Open Source
VULNERABLE: Information not available — no affected version range provided by NVD
CVSS VECTOR BREAKDOWN 4.2
AV: N Attack Vector Network
AC: H Attack Complexity High
PR: L Privileges Required Low
UI: N User Interaction None
S: U Scope Unchanged
C: L Confidentiality Low
I: L Integrity Low
A: N Availability None
4.2
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2026-93999 is an authorization weakness in the OpenID Connect (OIDC) token refresh implementation of Keycloak, an open-source identity and access management (IAM) solution. Keycloak fails to verify that a target audience client is still enabled before restoring requested audiences from stored client IDs and issuing a new access token, allowing a client holding a valid refresh token to keep obtaining access tokens for a disabled client. The impact is a bypass of administrative access controls on resource servers that perform offline JWT validation, enabling persistent access for disabled or deprovisioned OIDC clients.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Technical Analysis

Keycloak is widely deployed as an SSO and OIDC/OAuth 2.0 identity provider. In OIDC and OAuth 2.0, the refresh token grant allows a client to exchange a long-lived refresh token for new access tokens without re-authentication. Access tokens are JWTs that carry an "aud" (audience) claim indicating the intended recipient resource server(s). In Keycloak, the set of audiences is derived from configured client IDs, and during the refresh flow the server restores requested audiences from stored client IDs.

The flaw (classified as CWE-862, Missing Authorization) is that Keycloak does not verify whether the audience client referenced by a refresh request is still enabled before minting a new access token. Enforcement of the client's enabled/disabled state is effectively missing at token-refresh time. An application that already holds a valid refresh token can therefore continue to request — and successfully receive — valid access tokens scoped to a disabled client. Because the resulting tokens are otherwise validly signed JWTs, resource servers that rely on offline JWT validation (signature and claims only, without an online lookup of client state at the authorization server or introspection endpoint) will accept them.

Attack surface and conditions:

  • Network-exposed OIDC token endpoint (the refresh grant is a network request). The CVSS vector reflects AV:N (network), AC:H (high attack complexity), PR:L (low privileges required), UI:N (no user interaction), S:U (unchanged scope), C:L/I:L/A:N (low confidentiality and integrity impact, no availability impact).
  • The attacker must already possess a valid refresh token for the target client (PR:L and AC:H reflect this precondition and reduced exploitability).
  • Exploitation is silent and requires no user interaction. No public PoC, exploit code, or Nuclei template is available; the attack chain below is inferred from the vulnerability class (missing authorization on client state during token refresh).

Note: the NVD description does not disclose specific endpoint paths, parameter names, class names, or the exact code location responsible. No such specifics are invented here. The affected Keycloak version range is not provided in the available data; only products/versions confirmed to be affected should be treated as in-scope until the vendor clarifies.

Exploitation Scenarios

The following is inferred at the vulnerability-class level; no public PoC exists, and no implementation-specific identifiers are asserted beyond those stated in the NVD description.

  1. Reconnaissance / target identification

    • Identify Keycloak deployments (realm endpoints, login page, OIDC discovery metadata).
    • Identify resource servers that accept Keycloak-issued JWTs and perform offline JWT validation (verifying signature and claims locally) rather than online introspection, since these are the systems that will trust tokens issued for a disabled client.
  2. Triggering the specific flaw class

    • The actor must already hold a valid refresh token for a client that is subsequently disabled (for example, a client belonging to a deprovisioned application, an offboarded integration, or one disabled after a security incident).
    • The actor submits a refresh-token grant to the token endpoint. Because Keycloak restores requested audiences from stored client IDs but does not check whether the target audience client is still enabled, it issues a new access token instead of rejecting the request. This is a missing-authorization condition: the state change (client disabled) is not enforced at the authorization decision point (token refresh).
  3. Execution method (vulnerability class)

    • This is an authentication/authorization logic flaw exercised over a normal, standard OIDC refresh request. There is no memory corruption, injection payload, or file-upload step. Success is achieved by simply performing the refresh; the "payload" is the valid refresh token plus the requested audience/client. No specific API parameter names are asserted because the description does not provide them.
  4. Post-exploitation impact

    • The attacker obtains fresh, cryptographically valid access tokens for a client that administrators believe has been disabled.
    • Resource servers relying on offline JWT validation accept these tokens, granting the actor continued API access, data reads (C:L) and potentially state changes (I:L) that the disablement was intended to revoke.
    • Because the refresh token can be reused repeatedly, the actor can maintain persistent access as long as the refresh token remains valid and the preconditions hold — effectively bypassing administrative access revocation.

Impact Assessment

  • Business impact: Undermines the integrity of administrative deprovisioning. Disabling a client is a common containment action after compromise or offboarding; this flaw lets that control be bypassed, extending the window of unauthorized access to resource servers.
  • Affected systems: Keycloak IAM deployments acting as the OIDC provider, and downstream resource servers/APIs that validate Keycloak-issued JWTs offline (without introspection or client-state checks).
  • Blast radius: Scoped (S:U) and limited in direct measured severity — confidentiality low (C:L) and integrity low (I:L), with no availability impact (A:N). CVSS base 4.2 reflects high attack complexity (AC:H) driven by the requirement to already hold a valid refresh token, and low privileges (PR:L). Impact increases materially where a disabled client previously had broad audience access to many resource servers or high-value APIs.
  • Severity caution: A base score of 4.2 understates operational risk in environments that treat client disablement as a hard revocation control; the primary harm is control-plane bypass, not a high C/I/A delta.

Detection Guidance

Detection targets the behavioral anomaly: successful token refreshes that reference or yield audiences for clients that are disabled, and the resulting offline-validated token usage. The rules below are behavioral/heuristic and should be tuned to the environment. They do not depend on invented endpoint or parameter names.

Sigma Rule

title: Keycloak Refresh Token Issued for Disabled OIDC Client (CVE-2026-93999)
id: 7f3c1b2a-9d4e-4a10-9c2b-keycloak93999
status: experimental
description: Detects token refresh events where Keycloak issues an access token for an audience/client that is disabled (missing authorization check during refresh).
references:
  - https://nvd.nist.gov/vuln/detail/CVE-2026-93999
author: valtersit.com
date: 2026-01-01
logsource:
  product: keycloak
  service: token
detection:
  selection_event:
    event_type:
      - 'REFRESH_TOKEN'
      - 'TOKEN_REFRESH'
      - 'REFRESH_TOKEN_ERROR'
  selection_suspicious:
    client_enabled: false
  condition: selection_event and selection_suspicious
fields:
  - user
  - clientId
  - audience
  - ipAddress
  - realm
falsepositives:
  - Legitimate administrative testing where a client is intentionally disabled.
  - Log schema differences across Keycloak versions; adjust field names to your event schema.
level: medium

YARA Rule

rule Keycloak_Refresh_Token_Disabled_Client_CVE_2026_93999
{
    meta:
        description = "Heuristic detection of Keycloak token refresh activity referencing a disabled OIDC client (CVE-2026-93999). Intended for log or text artifacts placed in scanned files, not for binary memory."
        author = "valtersit.com"
        reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-93999"
        date = "2026-01-01"
        severity = "medium"

    strings:
        $refresh = "refresh_token" ascii nocase
        $grant   = "grant_type=refresh_token" ascii nocase
        $aud     = "audience" ascii nocase
        $disabled = "enabled" ascii nocase
        $kc      = "keycloak" ascii nocase

    condition:
        uint32(0) == 0x7B or uint32(0) == 0x5B or
        (2 of ($refresh, $grant, $aud) and $kc) or
        ($grant and $aud and $disabled)
}

Suricata IDS Rule

alert http any any -> any any (msg:"CVE-2026-93999 Keycloak OIDC Refresh Token Grant - Disabled Client Audience Reuse"; flow:established,to_server; http.method; content:"POST"; http.header; content:"application/x-www-form-urlencoded"; content:"grant_type=refresh_token"; http_client_body; content:"grant_type=refresh_token"; http_client_body; content:"refresh_token"; threshold:type both, track by_src, count 5, seconds 60; classtype:attempted-user; reference:cve,2026-93999; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-93999; sid:202693999; rev:1;)

Elastic Detection

sequence by source.ip, user.id with maxspan=5m
  [ authentication where event.action == "refresh_token" and keycloak.client.enabled == false ]
  [ authentication where event.outcome == "success" and event.category == "authentication" ]

Splunk SPL Query

index=keycloak sourcetype=keycloak:events (event_type=REFRESH_TOKEN OR grant_type=refresh_token)
| eval client_state=coalesce(client_enabled, client.enabled)
| where client_state="false" OR client_state=false
| stats count values(audience) as audiences values(clientId) as clients by user, src_ip, realm
| where count >= 3
| sort - count

Wazuh OSSEC Rule

<group name="keycloak,oidc,cve-2026-93999,">
  <rule id="100399" level="10">
    <decoded_as>json</decoded_as>
    <field name="event_type">REFRESH_TOKEN</field>
    <field name="client_enabled">false</field>
    <description>CVE-2026-93999: Keycloak issued access token via refresh for a disabled OIDC client</description>
    <mitre>
      <id>T1078</id>
    </mitre>
    <group>access_control_bypass,</group>
  </rule>
</group>

Mitigation & Patch Guidance

Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). Vendor fix: N/A. Workarounds: N/A as published.

  1. Immediate mitigations (compensating controls, since no patch exists)

    • Revoke/rotate refresh tokens for any clients that have been disabled; do not rely on client disablement alone as a revocation mechanism.
    • Disable or restrict the refresh token lifespan and enforce refresh token rotation where supported.
    • On resource servers, replace purely offline JWT validation with online token introspection or a client-state check so tokens issued for disabled clients are rejected at the point of use.
    • Monitor for refreshes referencing disabled clients (see Detection Guidance) and alert on repeat grant_type=refresh_token activity for disabled client IDs.
    • Apply network/host controls to restrict token endpoint access to trusted clients (PR:L precondition reflects that a valid refresh token is required).
  2. Patch / upgrade steps

    • No patch is available as of this writing. Track Keycloak security advisories and the NVD entry; monitor for a fixed release from the vendor. Do not assume a fix exists.
    • When a vendor fix is released: stage and validate in a non-production realm, then upgrade the Keycloak server. Re-verify that disabled-client enforcement is applied during refresh. Back up realm configuration before upgrade.
  3. Long-term hardening

    • Treat administrative disablement as a soft control and pair it with token revocation and secret rotation.
    • Adopt online introspection or short-lived access tokens with strict audience validation on resource servers.
    • Enforce least privilege on client audiences to limit the blast radius of any single client.
    • Continuously audit client enabled-state vs. issued tokens, and integrate IAM events into the SIEM.

References

Exploit-in-the-wild evidence: None. No public PoC, exploit code, or Nuclei template is available, and there is no known threat-actor campaign associated with this CVE at this time.

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2026-93999/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.