Like a customs officer who stamps passports left on the desk from before the security gate was raised
CVE-2026-86345 is a StartTLS plaintext buffer retention flaw in 389-ds-base — the LDAP directory server powering Red Hat Directory Server, FreeIPA/IdM, and RHEL identity infrastructure. When a client initiates a StartTLS upgrade on port 389, the server replaces the socket with a TLS-wrapped one but fails to flush pre-TLS plaintext bytes from the connection buffer. An on-path attacker who injects a crafted LDAP message (e.g., an anonymous BindRequest with a predictable messageID) into the same TCP segment as the StartTLS request can cause the server to process that smuggled message *after* TLS is active. The server delivers the forged response — a successful bind — through the encrypted channel, and the client's PAM/SSSD module accepts it as genuine. Confirmed vulnerable: 389-ds-base-2.6.1-6.el9_6. Affected across Red Hat Directory Server 11/12/13 and RHEL 6 through 10 plus all derivatives (AlmaLinux, Oracle Linux, Rocky, CentOS Stream, Fedora).
Red Hat rates this CRITICAL at 9.0 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H). The AC:H accurately captures the MITM prerequisite, and S:C is appropriate because the impact crosses from the directory server to every downstream client trusting LDAP bind results. However, the score slightly overstates *immediate* urgency: there is no public PoC, no in-the-wild exploitation, and the attack requires an already-compromised internal network position. One report suggests Red Hat's own qualitative rating is actually Moderate despite the 9.0 base score. noisgate holds the CRITICAL floor regardless, because 389-ds-base is canonically identity infrastructure — the vast majority of its installations serve as the authentication backbone for Linux environments — and a successful exploit means domain-scale authentication bypass. We adjust the score to 8.6 to reflect the no-PoC, no-exploitation reality while honoring the blast-radius floor.
Under the noisgate mitigation SLA for CRITICAL, deploy the primary compensating control — switching all 389-ds-base instances to LDAPS-only on port 636 by disabling the plaintext port — within 3 days. This single change eliminates the entire StartTLS attack surface. Under the noisgate remediation SLA, apply the vendor patch (via RHSA-2026:64784 or your distro's equivalent) within 90 days to fully resolve the underlying buffer handling defect. If KEV listing or active exploitation evidence emerges, override both timelines and patch immediately.
5 steps from start to impact.
Establish on-path position
- Internal network access (post-initial-compromise)
- Ability to perform ARP spoofing or equivalent Layer 2 MITM
- Requires prior compromise of a host on the same subnet or VLAN
- Dynamic ARP Inspection (DAI) on managed switches blocks ARP poisoning
- 802.1X port-based NAC limits rogue host placement
- Not achievable from the internet in any standard enterprise deployment
Identify StartTLS negotiation
1.3.6.1.4.1.1466.20037). This signals the client is about to upgrade the plaintext connection to TLS — the exact window the vulnerability exploits. Bettercap or a custom Scapy packet filter identifies this transition in real time.- Active MITM position on port 389
- Target environment using StartTLS (not LDAPS on port 636)
- Environments enforcing LDAPS-only on port 636 are completely immune — no plaintext phase exists
- LDAP client configurations using
ldaps://URIs bypass this entire path
Inject smuggled LDAP message into TCP segment
- Ability to modify TCP segments in transit (on-path, so trivial)
- Knowledge of the expected messageID (sequential in most LDAP client libraries — typically 1, 2, 3)
- Requires precise TCP injection timing within the StartTLS upgrade window
- Rare LDAP client implementations may use non-sequential messageIDs
Server processes stale buffer post-TLS upgrade
nsslapd-allow-anonymous-access: on), the server generates a BindResponse with result code 0 (success) and the attacker-chosen messageID, delivered through the now-encrypted channel.- Unpatched 389-ds-base
- Default configuration (anonymous access enabled, connection buffering active)
- Disabling anonymous access raises the bar but does not fully mitigate — the attacker can inject other operations that return a predictable result
Client accepts forged authentication
nss-pam-ldapd, SSSD, or any application using libldap) receives the forged BindResponse with the matching messageID through the TLS channel. It interprets result code 0 as a successful bind and grants the user access. The attacker can now authenticate as any user whose password they do not know, achieving authentication bypass across the entire fleet trusting this directory server.- Client application trusts LDAP bind responses without additional verification
- No secondary authentication factor enforced at the application layer above LDAP
- Applications using LDAP only for group/attribute lookups (not authentication) are unaffected by auth bypass
- MFA enforced at the application layer (e.g., TOTP/FIDO2 via SSSD MFA or PAM stacking) catches the bypass for interactive logins
nsslapd-port: 0 and ensure nsslapd-secureport: 636 with nsslapd-security: on in each instance's dse.ldif. Update all clients (/etc/sssd/sssd.conf, /etc/nslcd.conf, application LDAP URIs) to use ldaps:// scheme. Deploy within 3 days per the noisgate mitigation SLA for CRITICAL.nsslapd-accesslog-level: 256) and feed logs into SIEM. Alert on: anonymous bind immediately after StartTLS upgrade on the same connection; successful client-side login (via PAM/SSSD) with no corresponding successful BIND for that DN in DS logs. This is detection-only — it does not prevent exploitation but provides high-confidence incident signal. Deploy within 3 days.- WAF / reverse proxy — LDAP is not HTTP; web application firewalls do not inspect or filter LDAP protocol traffic on port 389/636. Completely irrelevant to this attack path.
- EDR on the directory server — This is a protocol-level attack exploiting a buffer-handling defect in the LDAP server process. No malware is dropped, no shell is spawned on the DS host, no file is written. EDR behavioral signatures have nothing to match.
- Setting
nsslapd-minssfto require encryption — The smuggled message is processed *after* TLS is established, so the minimum security strength factor threshold is already satisfied when the forged response is generated. minssf does not flush the pre-TLS buffer. - Disabling anonymous access (
nsslapd-allow-anonymous-access: off) — While anonymous bind is the easiest injection payload (always succeeds), an attacker can inject any LDAP operation that returns a predictable result code and messageID. Disabling anonymous access slightly raises the bar but does not close the vulnerability. - LDAP client-side certificates (mutual TLS) — The TLS channel itself is legitimate; the attack exploits pre-TLS buffered content processed inside the established TLS session. Client certificates authenticate the tunnel, not the stale buffer content.
The supporting signals.
| In-the-wild exploitation | None observed. Not listed in CISA KEV. Not flagged in any threat intelligence feed as of 2026-10-02. SecurityOnline explicitly marks status as 'Not exploited.' |
|---|---|
| PoC availability | No public PoC. Nothing found on pocindex.io, GitHub (no CVE-named repos), ExploitDB, or nuclei templates as of 2026-10-02. No researcher has published exploitation tooling. |
| EPSS score | Not yet computed. Disclosed 2026-10-02; FIRST EPSS requires 24–48 hours post-NVD publication. Expect a moderate-to-low EPSS given AC:H and the on-path requirement. |
| KEV status | Not listed in CISA Known Exploited Vulnerabilities catalog as of 2026-10-02. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H (9.0) — Network-accessible but high complexity (on-path/MITM). No privileges or user interaction. Scope changed: impact crosses from the directory server to all downstream authentication clients. All CIA metrics high. |
| Affected versions | 389-ds-base across Red Hat Directory Server 11/12/13, RHEL 6–10, AlmaLinux 8/9/10, Oracle Linux, Rocky Linux, CentOS Stream, Fedora. Confirmed on 389-ds-base-2.6.1-6.el9_6. Any instance with StartTLS on port 389 is exposed. |
| Fixed versions | Patches shipping via RHSA-2026:64784 (RHEL 9), OESA-2026-4114 (Oracle Linux), ALSA-2026:64784 (AlmaLinux 9), ALAS2-2026-3957 (Amazon Linux 2). Specific fixed package version strings not yet confirmed — check your distro's advisory tracker. NVD status: 'Received' (analysis pending). |
| Scanning / exposure | LDAP port 389 is overwhelmingly internal-facing. Shodan indexes <50,000 internet-exposed 389-ds instances globally; the vast majority sit behind the perimeter. The on-path requirement further constrains the reachable attacker population to LAN-adjacent threat actors. |
| Disclosure timeline | Reported to Red Hat 2026-09-07 via Bugzilla #2529332. Public disclosure 2026-10-02. NVD entry received same day; full analysis pending. |
| Reporter | Not attributed to a named external researcher. Imported via OSIDB Bzimport (Red Hat internal security tooling). No external credit in any published advisory. |
Sources.
Why this verdict
- Identity infrastructure floor: 389-ds-base is canonically an identity provider — it IS the LDAP directory backing FreeIPA/IdM, RHEL/CentOS/Fedora authentication, and countless Linux-shop SSO integrations. The overwhelming majority of its installations (>90%) serve as production identity infrastructure. A successful exploit means fleet-wide authentication bypass — any user, any host trusting that directory. Per noisgate's deployment-role blast radius rules, the verdict floor is CRITICAL and friction cannot pull below it.
- On-path requirement is real but already priced into AC:H (no double-penalty): The CVSS vector's AC:H captures the MITM prerequisite. On internal LANs without DAI, ARP spoofing is straightforward for a post-compromise attacker (Bettercap, ettercap, Responder). This is a friction point, but applying a second downward adjustment for what CVSS already accounts for would be double-counting.
- No PoC and no exploitation reduce immediacy (score −0.4 from 9.0 → 8.6): As of disclosure day (2026-10-02), no public PoC exists, no weaponized tooling has surfaced, and no in-the-wild exploitation has been observed. This meaningfully lowers the probability of near-term exploitation, justifying a score reduction while maintaining the CRITICAL severity bucket.
- Role multiplier: In its canonical deployment as a FreeIPA/IdM backend or standalone Red Hat Directory Server, a successful exploit yields identity-scale compromise — every Linux host, sudo policy, SSH key trust, HBAC rule, and SSSD-cached credential backed by that directory is subverted. On a workstation-as-LDAP-client (low-value role), impact is limited to that host's login. On a production Directory Server instance (high-value role, representing >90% of the installed base by definition), the blast radius is domain-equivalent → fleet-scale. The CRITICAL floor holds.
Why not higher?
A score of 9.0 or above would require either lower attack complexity (AC:L — e.g., remotely exploitable without MITM), active in-the-wild exploitation, or a public PoC lowering the attacker skill bar. The on-path prerequisite is genuine — it requires prior internal access and Layer 2 manipulation, which is a meaningful bar even for sophisticated post-compromise actors. The absence of any public PoC or weaponized tooling further limits immediate risk. The vendor's 9.0 slightly overstates current real-world exploitability given day-zero conditions.
Why not lower?
Downgrading to HIGH or below would require evidence that the identity-infrastructure deployment role represents <10% of the installed base, which it does not — 389-ds-base exists *primarily* to serve as an LDAP directory for authentication and identity. A generic 'requires internal access' argument is insufficient to break the CRITICAL floor when the target is the authentication backbone of a Linux domain. The consequence of a successful chain — fleet-wide authentication bypass with no credential knowledge — demands CRITICAL-tier response timelines regardless of exploitation probability.
Crowdsourced verification payload.
Run as root (or the dirsrv user) on each host running 389-ds-base / Red Hat Directory Server. Invoke: sudo bash cve_2026_86345_check.sh. No arguments. Checks all local DS instances for StartTLS exposure. Outputs VULNERABLE, PATCHED, or UNKNOWN.
#!/usr/bin/env bash
# CVE-2026-86345 checker — 389-ds-base StartTLS buffer retention auth bypass
# Run as root on each 389-ds-base host.
# Exit codes: 0 = PATCHED/NOT APPLICABLE, 1 = VULNERABLE, 2 = UNKNOWN
set -uo pipefail
echo "=== CVE-2026-86345: 389-ds-base StartTLS Buffer Retention ==="
echo ""
# 1. Check if 389-ds-base is installed
if ! rpm -q 389-ds-base &>/dev/null 2>&1; then
echo "[*] 389-ds-base is NOT installed on this host."
echo "PATCHED" # Not applicable — software not present
exit 0
fi
PKG=$(rpm -q 389-ds-base)
echo "[*] Installed package: $PKG"
# 2. Scan each Directory Server instance
EXPOSED=0
MITIGATED=0
NO_INSTANCES=1
for CONF in /etc/dirsrv/slapd-*/dse.ldif; do
[ -f "$CONF" ] || continue
NO_INSTANCES=0
INST=$(echo "$CONF" | grep -oP 'slapd-\K[^/]+')
echo ""
echo "[*] Instance: $INST"
PORT=$(awk -F': ' '/^nsslapd-port:/{print $2; exit}' "$CONF" 2>/dev/null)
SEC=$(awk -F': ' 'tolower($0) ~ /^nsslapd-security:/{print tolower($2); exit}' "$CONF" 2>/dev/null)
SECPORT=$(awk -F': ' '/^nsslapd-secureport:/{print $2; exit}' "$CONF" 2>/dev/null)
echo " Plaintext port (StartTLS): ${PORT:-389}"
echo " nsslapd-security: ${SEC:-off}"
echo " Secure port (LDAPS): ${SECPORT:-636}"
if [[ "${PORT:-389}" != "0" && "${SEC:-off}" == "on" ]]; then
echo " !! StartTLS path is ENABLED on port ${PORT:-389} — EXPOSED"
EXPOSED=1
elif [[ "${PORT:-389}" == "0" ]]; then
echo " Plaintext port disabled (LDAPS-only) — mitigated."
MITIGATED=1
else
echo " TLS not enabled at all — not exposed to THIS CVE,"
echo " but plaintext LDAP without any encryption is a larger issue."
MITIGATED=1
fi
done
echo ""
if [[ $NO_INSTANCES -eq 1 ]]; then
echo "[*] No Directory Server instances found in /etc/dirsrv/."
echo "PATCHED" # Not applicable
exit 0
fi
if [[ $EXPOSED -eq 1 ]]; then
echo "VULNERABLE"
echo "ACTION: Set nsslapd-port: 0 to disable plaintext port,"
echo " enforce LDAPS on port 636, update all client URIs"
echo " to ldaps://, or apply vendor patch."
exit 1
elif [[ $MITIGATED -eq 1 ]]; then
echo "PATCHED"
echo "(Mitigated: LDAPS-only mode; StartTLS upgrade path not reachable.)"
exit 0
else
echo "UNKNOWN"
echo "Manual review of instance configuration required."
exit 2
fi