PT-2026-59245 · Pypi · Lemur
Published
2026-07-13
·
Updated
2026-07-13
CVSS v3.1
6.8
Medium
| Vector | AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N |
Description
Overview
When LDAP TLS is enabled (
LDAP USE TLS = True), Lemur's LDAP authentication module unconditionally disables TLS certificate verification at the global ldap module level. This allows a man-in-the-middle attacker positioned between Lemur and the LDAP server to intercept all authentication credentials.Vulnerable Code
Location:
lemur/auth/ldap.py, bind() method, line ~172python
if self.ldap use tls:
ldap.set option(ldap.OPT X TLS REQUIRE CERT, ldap.OPT X TLS NEVER)Key issues:
ldap.set option()is a global call (as opposed toself.ldap client.set option()), meaning it disables TLS verification for the entire Python process, not just this connectionOPT X TLS NEVERmeans no certificate validation is performed whatsoever — self-signed, expired, wrong hostname, and revoked certificates are all silently accepted- There is no configuration option to override this behavior — TLS verification is always disabled when TLS is enabled
Impact
A network-positioned attacker (man-in-the-middle) between Lemur and the LDAP server can:
- Intercept all LDAP credentials (usernames and plaintext passwords) for every user who authenticates
- Modify LDAP responses to inject arbitrary group memberships, granting admin access
- Compromise the entire PKI infrastructure managed by Lemur, since authentication controls access to certificates and private keys
This is particularly severe because Lemur is a certificate management system — the tool designed to manage TLS security is itself vulnerable to a TLS attack.
Steps to Reproduce
- Deploy Lemur with LDAP TLS enabled:
python
LDAP AUTH = True
LDAP USE TLS = True
LDAP BIND URI = "ldaps://dc.corp.example.com"- Intercept the LDAP connection using a TLS proxy (e.g.,
mitmproxyorstunnel):
bash
# Generate a self-signed certificate
openssl req -x509 -newkey rsa:2048 -keyout mitm.key -out mitm.crt -days 1 -nodes -subj "/CN=mitm"
# Proxy LDAP traffic
stunnel -d 0.0.0.0:636 -r real-ldap-server:636 -p mitm.pem-
Point Lemur's
LDAP BIND URIat the proxy (or perform ARP spoofing/DNS hijacking) -
Observe that Lemur connects without any certificate verification error
-
All credentials are visible in the proxy's TLS session
Remediation
Remove the global TLS verification bypass and default to strict verification:
python
if self.ldap use tls:
# Use instance-level option, not global
self.ldap client.set option(ldap.OPT X TLS REQUIRE CERT, ldap.OPT X TLS DEMAND)
self.ldap client.set option(ldap.OPT PROTOCOL VERSION, 3)
if self.ldap cacert file:
self.ldap client.set option(ldap.OPT X TLS CACERTFILE, self.ldap cacert file)If backward compatibility is needed, make it configurable with a secure default:
python
tls require cert = current app.config.get("LDAP TLS REQUIRE CERT", ldap.OPT X TLS DEMAND)
self.ldap client.set option(ldap.OPT X TLS REQUIRE CERT, tls require cert)Resources
- CWE-295: https://cwe.mitre.org/data/definitions/295.html
- python-ldap TLS documentation: https://www.python-ldap.org/en/python-ldap-3.4.0/reference/ldap.html#tls-options
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Lemur