CVE-2026-96445
Executive Summary
CVE-2026-96445 is an improper-authentication vulnerability (CWE-287) in the Conditional OTP authenticator of Keycloak, an open-source identity and access management (IAM) solution. The Conditional OTP authenticator evaluates specific HTTP headers to decide whether to skip the one-time password (OTP) step, but fails to validate that those headers originated from a trusted source. An attacker who has already obtained a victim's password can supply a specially crafted header and bypass the second factor, defeating multi-factor authentication (MFA) enforcement for affected deployments. The vulnerability is rated CVSS 6.8 (AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N) and remains unpatched per all tracked sources; no public PoC or Nuclei template exists.
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.
No signup required
Technical Analysis
Keycloak supports conditional authentication flows in which a configurable "Conditional OTP" authenticator decides at login time whether the OTP second factor must be presented. The NVD description states that this authenticator: (a) evaluates specific HTTP headers to make the skip/present decision, and (b) fails to verify that those headers came from a trusted source.
This is a trust-boundary failure. Any HTTP header sent by a client is attacker-controlled unless the deployment fronts Keycloak with a proxy that strips or overwrites external client values and injects a trusted value itself. Because the authenticator does not confirm header provenance, an attacker can set the header directly in the authentication request and cause the OTP step to be treated as unnecessary. The result is that the authenticator's decision logic is driven by attacker-supplied input rather than by verified infrastructure state.
Two preconditions gate exploitation:
- The attacker must already possess a valid username and password (confirmed by the CVSS vector
PR:L— low privilege/partial authentication — and by the description wording "an attacker who already has a user's password"). - The Conditional OTP authenticator must be configured in the target realm's authentication flow. Deployments using unconditional OTP or no OTP flow are unaffected.
The CVSS vector further characterizes the flaw: AC:H (high attack complexity) reflects that the attack requires knowledge of the specific header the environment uses and that access conditions may vary; UI:N (no user interaction) indicates the victim does not need to cooperate; S:U (scope unchanged) means the impact stays within Keycloak's security context; and C:H/I:H (high confidentiality and integrity impact) means a successful bypass grants full authenticated access to the victim account, including everything that account can read or modify. Availability (A:N) is not impacted.
No function names, class names, URL endpoints, file paths, or parameter names appear in the supplied NVD description or CNA title, and none are invented here. The precise header name(s) evaluated by the authenticator, the exact Keycloak version range, and the code path involved are not available from the provided intelligence. The vulnerability class is an unverified-header trust assumption in an authentication decision point. CWE-287 (Improper Authentication) is the assigned weakness, consistent with a second-factor check that can be neutralized by unauthenticated input.
Exploitation Scenarios
No public PoC is available; the attack chain below is inferred at the vulnerability-class level from the NVD description. It does not name specific functions, endpoints, or parameters because none are provided by the source data.
Reconnaissance / target identification. The attacker identifies a Keycloak-protected application, for example a login portal or administrative console presenting a Keycloak authentication flow. The attacker determines whether the realm has a Conditional OTP authenticator configured (e.g., by observing MFA behavior across test accounts or public knowledge of the deployment's authentication design).
Credential acquisition and precondition. The attacker obtains a victim's valid password through phishing, credential stuffing, password reuse, or a prior breach. This step is external to the CVE but is mandatory given CVSS
PR:L. At this point the attacker can pass the first factor but would normally be stopped by the OTP prompt.Triggering the flaw. The attacker submits an authentication request to Keycloak including the specially crafted HTTP header that the Conditional OTP authenticator inspects. Because the authenticator does not verify that the header originated from a trusted source (e.g., it does not require that a fronting proxy have stripped and re-injected the header), the attacker-supplied value is honored. The authenticator's logic concludes the OTP condition is satisfied or not applicable and skips the second-factor challenge. The specific header name and expected value are environment-dependent and are not disclosed in the available intelligence; the attacker's reconnaissance would target values leaked in documentation, misconfigured proxies, or header-reflecting responses.
Post-exploitation impact. Keycloak issues a fully authenticated session for the victim account. Depending on the client applications federated to that realm, the attacker inherits the account's full privileges — reading or modifying protected data (
C:H,I:H) and acting as the legitimate user across any relying party that trusts the issued tokens. This constitutes complete MFA bypass with no user interaction (UI:N).
Exploitation in the wild: no evidence of active campaigns, KEV listing, or public exploit code was found in the supplied data.
Impact Assessment
The core business impact is the loss of the security guarantee MFA is purchased to provide. Organizations that deployed Conditional OTP specifically to reduce friction while retaining a second factor now face a bypass that is silent from the victim's perspective — no OTP prompt appears, and the account may show a normal successful login.
- Affected systems: Keycloak realms configured with a Conditional OTP authenticator. The flaw lives in Keycloak's authentication flow logic, so any application or service federated to such a realm (SSO clients, APIs trusting Keycloak-issued tokens, administrative consoles) inherits the exposure.
- Blast radius: limited to accounts whose passwords an attacker has already obtained (precondition), but for those accounts the compromise is total. Because Keycloak commonly sits at the center of enterprise SSO, a single bypassed account can expose downstream SaaS and internal applications.
- CVSS interpretation:
C:HandI:Hconfirm high confidentiality and integrity loss;A:Nconfirms no availability impact;S:Uconfirms impacts stay within the vulnerable component's authority;AC:Hreflects the environmental knowledge and preconditions required rather than a trivially scriptable exploit.
Insufficient data is available to enumerate affected version ranges or quantify the number of exposed deployments.
Detection Guidance
The rules below target the vulnerability class: authentication requests carrying unexpected or externally supplied headers into Keycloak's OTP decision logic. Because the exact header name is not published, the detections focus on anomalous header presence in authentication traffic and on successful logins that skip the expected second factor. Tune header names to your environment after reviewing your Conditional OTP configuration.
Sigma Rule
title: Potential Keycloak Conditional OTP Bypass via Untrusted Header
id: 8f2c1a4e-9644-5cve-9644-000000000001
status: experimental
description: Detects authentication requests to Keycloak that include headers commonly used to signal trusted proxy or conditional authentication state from an untrusted client, potentially bypassing Conditional OTP (CVE-2026-96445).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-96445
author: valtersit.com
date: 2026/01/01
logsource:
category: webserver
detection:
selection_path:
cs-uri-stem|contains:
- '/realms/'
- '/auth/realms/'
- '/protocol/openid-connect/auth'
- '/protocol/openid-connect/token'
selection_headers:
cs-headers|contains:
- 'X-Forwarded-'
- 'X-Trusted-'
- 'X-Auth-'
- 'X-OTP-'
- 'X-Skip-'
condition: selection_path and selection_headers
fields:
- c-ip
- cs-uri-stem
- cs-headers
falsepositives:
- Legitimate reverse proxies that inject trusted headers (baseline and exclude proxy source IPs)
level: medium
tags:
- attack.defense_evasion
- attack.t1078
- cve.2026.96445
YARA Rule
rule CVE_2026_96445_Keycloak_ConditionalOTP_Header_Trust
{
meta:
description = "Detects Keycloak artifacts referencing conditional OTP header trust logic associated with CVE-2026-96445"
author = "valtersit.com"
reference = "https://nvd.nist.gov/vuln/detail/CVE-2026-96445"
date = "2026-01-01"
severity = "medium"
strings:
$kc1 = "ConditionalOtp" ascii nocase
$kc2 = "ConditionalOtpAuthenticator" ascii nocase
$kc3 = "Conditional OTP" ascii nocase
$hdr1 = "X-Forwarded" ascii nocase
$hdr2 = "X-Trusted" ascii nocase
$skip = "skipOtp" ascii nocase
condition:
(any of ($kc*)) and (any of ($hdr*) or $skip)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-96445 Keycloak Conditional OTP bypass attempt - untrusted header with auth request"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"/protocol/openid-connect/auth"; http.header; content:"X-"; http.header; pcre:"/(?i)X-(Forwarded|Trusted|OTP|Skip|Auth)-[^:]*:/"; classtype:attempted-user; reference:cve,2026-96445; reference:url,nvd.nist.gov/vuln/detail/CVE-2026-96445; sid:9644501; rev:1;)
Elastic Detection
sequence by source.ip with maxspan=30s
[network where http.request.method == "POST" and
url.path : ("*/protocol/openid-connect/auth", "*/realms/*") and
http.request.headers : "*X-*"]
[network where http.response.status_code == 302 and
url.path : ("*/protocol/openid-connect/*", "*/realms/*")]
Splunk SPL Query
index=web sourcetype=keycloak_access OR sourcetype=nginx:access
| eval hdr_count = mvcount(mvfilter(match("X-", _raw)))
| where (match(uri_path, "/realms/") OR match(uri_path, "/protocol/openid-connect/auth") OR match(uri_path, "/protocol/openid-connect/token"))
| rex field=_raw max_match=0 "(?i)(?<susp_hdr>X-(Forwarded|Trusted|OTP|Skip|Auth)-[A-Za-z0-9\-]+):"
| where isnotnull(susp_hdr)
| stats count values(susp_hdr) as suspicious_headers values(clientip) as src_ips by uri_path, status
| sort -count
Wazuh OSSEC Rule
<group name="web,keycloak,cve-2026-96445,">
<rule id="964450" level="10">
<decoded_as>json</decoded_as>
<field name="url">/realms/|/protocol/openid-connect/auth|/protocol/openid-connect/token</field>
<field name="http_headers">(?:X-Forwarded|X-Trusted|X-OTP|X-Skip|X-Auth)-</field>
<description>CVE-2026-96445: Possible Keycloak Conditional OTP bypass attempt - untrusted authentication header present</description>
<mitre>
<id>T1078</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source). No vendor fix version, advisory, or workaround is available in the supplied intelligence. Treat the following as interim risk-reduction measures until an authoritative patch is published.
Immediate mitigations:
- If Conditional OTP is not required, disable the Conditional OTP authenticator in affected realms and switch to unconditional OTP enforcement for all users, eliminating the header-driven skip decision.
- Ensure Keycloak is only reachable behind a trusted reverse proxy that strips any client-supplied headers used for conditional authentication and re-injects them only from trusted internal components. Block direct client access to Keycloak ports.
- Network-layer enforcement: reject or strip the specific headers the Conditional OTP authenticator consumes at the perimeter (WAF/proxy), so external clients cannot set them.
- Treat password-only compromise as an MFA bypass vector for these realms and prioritize phishing-resistant factors.
- Audit authentication logs for successful logins that completed without an OTP challenge for accounts where MFA was expected.
Patch/upgrade steps:
- No patch is available at time of writing. Monitor the Keycloak security advisories page and the CVE record for an official fixed release, then upgrade to the first patched version as soon as it is published.
- Because no affected-version range is published, inventory all Keycloak deployments and identify which realms use a Conditional OTP flow as part of remediation planning.
Long-term hardening:
- Adopt a "never trust client headers" principle for authentication decisions; require provenance verification for any header consumed by an authentication flow.
- Enforce network segmentation so Keycloak's authentication endpoints are reachable only via a hardened, header-sanitizing reverse proxy.
- Enforce strong, unique credentials and phishing-resistant MFA (WebAuthn/passkeys) to reduce the value of a password-only precondition.
- Continuously monitor vendor advisories and subscribe to Keycloak security announcements; re-evaluate workarounds once a CVSS/technical update or patch is released.
References
- NVD — CVE-2026-96445: https://nvd.nist.gov/vuln/detail/CVE-2026-96445
- Keycloak project security advisories: https://www.keycloak.org/security
- CWE-287 — Improper Authentication: https://cwe.mitre.org/data/definitions/287.html
- MITRE ATT&CK T1078 — Valid Accounts: https://attack.mitre.org/techniques/T1078/
- CISA Known Exploited Vulnerabilities catalog (confirm whether CVE-2026-96445 is later added): https://www.cisa.gov/known-exploited-vulnerabilities-catalog
No threat actor campaigns or exploit-in-the-wild evidence were identified in the provided data. EPSS is not yet scored by FIRST.org; no value is asserted here.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.