Automated Threat Modeling

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. Under default configurations, the backend silently treats disabled users as enabled.

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, so revoked accounts can keep authenticating across cloud infrastructure. For any organization that relies on LDAP directory state to revoke access in its OpenStack deployment, CVE-2026-40683 means that, under default configurations, disabling a user in LDAP has had no effect on their Keystone access since 2014.

Technical Information

The root cause is a logic error in the _ldap_res_to_model method of the UserApi class in Keystone's LDAP core module. This method translates raw LDAP directory entries into Keystone's internal user model. It converts the LDAP enabled attribute from a string to a boolean only when the user_enabled_invert configuration option is set to True. When user_enabled_invert is False (the default), Keystone uses the raw string from the LDAP server directly, with no type conversion.

Python's type semantics turn that into a security problem. In Python, any non-empty string is truthy. When an LDAP directory returns the string "FALSE" for a disabled user's enabled attribute, Keystone passes that string through unconverted. Python evaluates bool("FALSE") as True because the string is non-empty, so the disabled user is 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. The label fits, because Keystone's authorization logic expects a boolean and consumes a string instead.

Additional Failure Modes

Several related issues compound the primary vulnerability:

Missing Attributes: If an LDAP entry has no enabled attribute at all, Keystone falls back to the user_enabled_default configuration value. That default is the string "False", not the Python boolean False. As a non-empty string it is also truthy, so users who should be disabled by default are granted access.

Ignored Custom Attributes: Administrators who map the enabled state to a custom LDAP attribute such as IsActive find that Keystone ignores it unless the invert option is enabled, which defeats 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. Strict API clients that validate response schemas break as a result.

Attack Flow

Exploitation is simple and needs 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 convert the string to a boolean.
  6. Python evaluates the non-empty string "FALSE" as truthy.
  7. Keystone issues a valid authentication token. The user keeps 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. It reflects network accessibility, the need for valid (low-privilege) credentials, and a changed scope that indicates potential cross-tenant impact. The base score is 7.7 (High).

Affected Systems and Versions

All OpenStack Keystone deployments that use the LDAP identity backend without user_enabled_invert=True or user_enabled_emulation enabled are affected. The affected versions 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 been in the codebase since the Juno cycle (2014), so for long-running deployments the exposure window is more than a decade.

Vulnerable Configuration

The default Keystone LDAP configuration is vulnerable. That covers 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 runs 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 raise a process concern. The initial fix was merged publicly on the master branch in October 2025, through a public bug report (LP#2121152), before anyone recognized the full security implications. A second, more detailed bug report (LP#2141713) later identified the security impact, but by then the fix was already public. The embargo was dropped and the issue was disclosed immediately. Potential attackers could therefore see the vulnerability before a coordinated advisory was issued.

That the bug went undetected from 2014 onward also shows how hard type confusion is to catch in dynamically typed languages, particularly in integration code that bridges systems with different type representations.

References

Detect & fix
what others miss

Works with
  • GitHub
  • GitLab
  • Bitbucket
  • Azure DevOps Services
  • Gerrit
  • CVS
  • Jira
  • Linear
  • Slack
  • Security Compass
Explore integrations
Security magnifying glass visualization