CVE-2025-61911 Overview
CVE-2025-61911 affects python-ldap, a lightweight directory access protocol (LDAP) client API for Python. In versions prior to 3.4.5, the ldap.filter.escape_filter_chars sanitization method can be bypassed when a crafted list or dict is supplied as the assertion_value parameter with the non-default escape_mode=1 configured. Applications relying on this method to sanitize untrusted input may be susceptible to LDAP injection [CWE-75], allowing an attacker to disclose or manipulate directory data outside their authorization scope. Version 3.4.5 remediates the issue by enforcing a type check that raises a TypeError when assertion_value is not a str.
Critical Impact
Attackers can inject unescaped LDAP metacharacters through non-string data types to alter query semantics, potentially exposing or modifying directory entries the application intends to protect.
Affected Products
- python-ldap versions prior to 3.4.5
- Python applications invoking ldap.filter.escape_filter_chars with escape_mode=1
- Downstream frameworks and identity integrations that pass user-controlled data to python-ldap filter builders
Discovery Timeline
- 2025-10-10 - CVE-2025-61911 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2025-61911
Vulnerability Analysis
The ldap.filter.escape_filter_chars function supports three escaping modes. escape_mode=0 (default) and escape_mode=2 raise exceptions when the caller passes a list or dict as assertion_value. escape_mode=1, which escapes all non-ASCII characters, iterates over the input without validating its type. When a list or dict is supplied, the function returns a value that has not been fully escaped, leaving LDAP metacharacters such as *, (, ), \, and NUL intact in downstream filter strings.
An attacker who controls the assertion_value fed into a filter can inject filter fragments that broaden search scope, bypass authentication predicates, or alter comparison logic. The resulting LDAP injection can disclose attributes protected by application-level filters or manipulate query results in identity, authorization, and lookup flows.
Root Cause
The root cause is missing input type validation in Lib/ldap/filter.py. The function assumed assertion_value would always be a str, but accepted other iterable types under escape_mode=1 and processed them without applying the character-escaping logic to the underlying data.
Attack Vector
Exploitation requires an application that:
- Uses python-ldap < 3.4.5.
- Invokes escape_filter_chars with escape_mode=1.
- Passes attacker-influenced data whose type is not strictly enforced as str.
Under these conditions, an attacker submits a list or dict structure that survives sanitization and reaches the LDAP server as an injected filter.
# Security patch in Lib/ldap/filter.py (python-ldap 3.4.5)
# If 1 all NON-ASCII chars are escaped.
# If 2 all chars are escaped.
"""
if not isinstance(assertion_value, str):
raise TypeError("assertion_value must be of type str.")
if escape_mode:
r = []
if escape_mode==1:
# Source: https://github.com/python-ldap/python-ldap/commit/3957526fb1852e84b90f423d9fef34c7af25b85a
The patch adds an explicit isinstance check that rejects any assertion_value that is not a str, closing the type-confusion path that bypassed escaping.
Detection Methods for CVE-2025-61911
Indicators of Compromise
- LDAP server logs showing filters containing unescaped *, (, ), or \ characters originating from application-side queries.
- Unusually broad LDAP search filters or repeated authentication queries with anomalous predicate structures.
- Application error logs referencing escape_filter_chars invocations with non-string types prior to patching.
Detection Strategies
- Perform a software composition analysis (SCA) scan of Python dependencies to identify python-ldap versions below 3.4.5.
- Audit source code for calls to ldap.filter.escape_filter_chars using escape_mode=1 and verify upstream input is coerced to str.
- Instrument LDAP client libraries to log final filter strings and alert on unexpected metacharacters after sanitization.
Monitoring Recommendations
- Enable verbose LDAP audit logging on directory servers to capture the full filter strings issued by application service accounts.
- Baseline normal filter patterns per application and alert on deviations, such as wildcard expansions or boolean operator injections.
- Track dependency inventories with continuous vulnerability feeds to catch future python-ldap advisories.
How to Mitigate CVE-2025-61911
Immediate Actions Required
- Upgrade python-ldap to version 3.4.5 or later across all environments.
- Enforce str types at the application layer before passing values to any LDAP filter builder.
- Review any code paths that intentionally use escape_mode=1 and validate input handling around them.
Patch Information
The fix is available in python-ldap 3.4.5. Refer to the GitHub Security Advisory GHSA-r7r6-cc7p-4v5m and the upstream commit 3957526. Release notes are published at the python-ldap 3.4.5 release page.
Workarounds
- Explicitly cast or validate assertion_value with isinstance(value, str) before calling escape_filter_chars.
- Avoid the non-default escape_mode=1 when handling untrusted input; the default escape_mode=0 raises on non-string inputs.
- Reject requests containing non-scalar structures for parameters destined to LDAP filters at the API or form layer.
# Upgrade python-ldap across environments
pip install --upgrade 'python-ldap>=3.4.5'
# Verify installed version
python -c "import ldap; print(ldap.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

