Brief Summary: OpenStack Keystone CVE-2026-40683 LDAP Type Confusion Lets Disabled Users Authenticate

A brief summary of CVE-2026-40683, a high severity type confusion flaw in OpenStack Keystone's LDAP identity backend that silently treats disabled users as enabled under default configurations.

CVE Analysis

7 min read

ZeroPath CVE Analysis
ZeroPath CVE Analysis

2026-04-14

Brief Summary: OpenStack Keystone CVE-2026-40683 LDAP Type Confusion Lets Disabled Users Authenticate
Experimental AI-Generated Content

This CVE analysis is an experimental publication that is completely AI-generated. The content may contain errors or inaccuracies and is subject to change as more information becomes available. We are continuously refining our process.

If you have feedback, questions, or notice any errors, please reach out to us.

[email protected]

Introduction

A decade old logic error in OpenStack Keystone's LDAP identity backend silently treats disabled users as enabled, allowing revoked accounts to continue authenticating across cloud infrastructure. For any organization relying on LDAP directory state to enforce access revocation in their OpenStack deployment, CVE-2026-40683 means that disabling a user in LDAP has had no effect on their Keystone access under default configurations since 2014.

Technical Information

The root cause is a logic error in the _ldap_res_to_model method within the UserApi class of Keystone's LDAP core module. This method translates raw LDAP directory entries into Keystone's internal user model. The code only performs string to boolean conversion of the LDAP enabled attribute when the user_enabled_invert configuration option is set to True. When user_enabled_invert is False (the default), the raw string value returned by the LDAP server is used directly without any type conversion.

This is where Python's type semantics create a security problem. In Python, any non empty string evaluates as truthy. When an LDAP directory returns the string "FALSE" for a disabled user's enabled attribute, Keystone passes that string through without conversion. Python evaluates bool("FALSE") as True because the string is non empty. The disabled user is therefore treated as enabled and can authenticate normally.

The vulnerability is classified as CWE 843 (Access of Resource Using Incompatible Type), commonly known as Type Confusion. This accurately describes the mismatch between the expected boolean type and the actual string type being consumed by Keystone's authorization logic.

Additional Failure Modes

Several related issues compound the primary vulnerability:

Missing Attributes: If an LDAP entry lacks the enabled attribute entirely, Keystone falls back to the user_enabled_default configuration value. This default is the string "False" rather than a Python boolean False. Since it is a non empty string, it also evaluates as truthy, granting access to users who should be disabled by default.

Ignored Custom Attributes: Administrators who configure custom LDAP attributes such as IsActive to represent the enabled state find those attributes ignored unless the invert option is enabled, defeating the purpose of the custom mapping.

API Schema Violations: Because the raw string passes through the entire pipeline, the Keystone API returns the string "FALSE" in JSON responses instead of a proper JSON boolean false. This breaks strict API clients that validate response schemas.

Attack Flow

The exploitation path for this vulnerability is notably simple. It requires no special tooling or exploit code:

  1. A user account is disabled in the organization's LDAP directory (e.g., a terminated employee, a revoked contractor, or a compromised account that was locked).
  2. The LDAP server stores the disabled status as a string attribute, such as enabled: FALSE.
  3. The user (or an attacker with the user's credentials) attempts to authenticate to Keystone.
  4. Keystone queries LDAP and receives the enabled attribute as the string "FALSE".
  5. Because user_enabled_invert is False (the default), Keystone does not perform string to boolean conversion.
  6. Python evaluates the non empty string "FALSE" as truthy.
  7. Keystone issues a valid authentication token. The user retains all previously assigned roles across tenants and services.

The CVSS 3.1 vector is AV:N/AC:H/PR:L/UI:N/S:C/C:L/I:L/A:H, reflecting network accessibility, the requirement for valid (low privilege) credentials, and a changed scope indicating potential cross tenant impact. The base score is 7.7 (High).

Affected Systems and Versions

All OpenStack Keystone deployments using the LDAP identity backend without user_enabled_invert=True or user_enabled_emulation enabled are affected. The specific version ranges by release branch are:

Release BranchAffected Versions
Gazpacho 2026.128.0.0 through 28.0.1
Flamingo 2025.227.0.0 through 27.0.1
Epoxy 2025.126.0.0 through 26.1.1
Dalmatian 2024.28.0.0 through 25.0.1

The Caracal 2024.1 branch is at end of maintenance and will not receive a backport.

The bug has existed in the codebase since the Juno cycle (2014), meaning the exposure window spans over a decade for long running deployments.

Vulnerable Configuration

The default Keystone LDAP configuration is vulnerable. Specifically, any deployment where:

  • The LDAP identity backend is in use
  • user_enabled_invert is set to False (the default)
  • user_enabled_emulation is not enabled

Vendor Security History

OpenStack maintains a mature security program through its Vulnerability Management Team, which handles incoming reports and publishes OpenStack Security Advisories (OSSAs) and OpenStack Security Notes (OSSNs). This vulnerability was tracked as OSSA 2026 007.

The handling of this issue does highlight a process concern. The initial fix was merged publicly on the master branch in October 2025 via a public bug report (LP#2121152) before the full security implications were recognized. A second, more detailed bug report (LP#2141713) subsequently identified the security impact, but by that point the fix was already public. The embargo was dropped, leading to immediate disclosure. This sequence gave potential attackers visibility into the vulnerability before a coordinated advisory could be issued.

The fact that this bug persisted undetected since 2014 also underscores the difficulty of identifying type confusion issues in dynamically typed languages, particularly in integration code that bridges systems with different type representations.

References

Detect & fix
what others miss

Security magnifying glass visualization