Pre-auth LDAP filter injection via CleanAllRUV status check extended operation
- CVE ID
- CVE-2026-11770
- Product
- 389-ds-base
- Severity
- Moderate (7.5)
- CVSS Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
- CWE
- CWE-90
- Red Hat CVE
- Red Hat CVE page
Summary
A vulnerability in the 389 Directory Server’s replication subsystem allows an unauthenticated remote attacker to extract sensitive server configuration data by injecting arbitrary LDAP search filters into a replication status-check extended operation. The affected handler multisupplier_extop_cleanruv_check_status() lacks any authentication or authorization checks, making it reachable via anonymous bind with default server configuration (nsslapd-allow-anonymous-access: on). The binary response to injected filters creates a boolean oracle that enables character-by-character extraction of 31 configuration attributes from the server’s cn=config subtree, including replication bind DNs, filesystem paths, password storage schemes, and ACI keywords.
Affected Versions
| Package | Version | Status |
|---|---|---|
| 389-ds-base (upstream) | 1.3.x through current | Vulnerable (confirmed) |
| 389-ds-base (RHEL 7 ELS) | 1.3.x | Vulnerable (confirmed, PoC tested) |
| 389-ds-base (RHEL 8) | 1.4.x | Vulnerable (code present) |
| 389-ds-base (RHEL 9) | 2.x | Vulnerable (code present) |
| 389-ds-base (RHEL 10) | 3.x | Vulnerable (code present) |
| 389-ds-base (Fedora 42) | 3.1.x | Vulnerable (confirmed, replication bind DN extraction tested) |
Affected Products
| Product | Version | Status |
|---|---|---|
| 389 Directory Server (upstream) | All with CleanAllRUV | Affected |
| Red Hat Directory Server 10-13 | 10.x through 13.x | Affected |
| RHEL 7 (IdM/FreeIPA) | 7.0 through 7.9 ELS | Affected |
| RHEL 8 (IdM/FreeIPA) | 8.0 through 8.10 | Affected |
| RHEL 9 (IdM/FreeIPA) | 9.0 through 9.6+ | Affected |
| RHEL 10 (IdM/FreeIPA) | 10.0 through 10.1 | Affected |
| Fedora | 39 through 43 | Affected |
Root Cause
File: ldap/servers/plugins/replication/repl_extop.c:1840-1885
Function: multisupplier_extop_cleanruv_check_status()
The function processes a REPL_CLEANRUV_CHECK_STATUS_OID (2.16.840.1.113730.3.6.8) extended operation by decoding a filter string from the BER request payload via decode_cleanruv_payload() and passing it unsanitized to an internal LDAP search against cn=config with the replication plugin’s elevated identity:
if (decode_cleanruv_payload(extop_payload, &filter)) {
/* error handling */
goto free_and_return;
}
search_pb = slapi_pblock_new();
slapi_search_internal_set_pb(search_pb, "cn=config", LDAP_SCOPE_SUBTREE,
filter, NULL, 0, NULL, NULL,
repl_get_plugin_identity(PLUGIN_MULTISUPPLIER_REPLICATION), 0);
slapi_search_internal_pb(search_pb);
Three design flaws compound the injection:
-
Missing authentication: The handler performs zero bind DN or authorization checks. Compare with
multisupplier_extop_StartNSDS50ReplicationRequest()at lines 838-841, which explicitly callsreplica_is_updatedn(). -
Privileged search identity: The search executes with
repl_get_plugin_identity(PLUGIN_MULTISUPPLIER_REPLICATION), bypassing the ACL framework that would normally restrict access to sensitivecn=configattributes. -
Boolean oracle response: The function returns
CLEANRUV_FINISHED(no entries matched) orCLEANRUV_CLEANING(entries matched), creating a deterministic boolean oracle from the injected filter’s result.
Proof of Concept
Two PoC scripts are provided.
PoC 1: Filter Injection Oracle
poc/021-cleanruv-filter-injection.py
Full 5-phase demonstration of the boolean oracle: baseline confirmation, attribute presence probing, substring extraction, password limitation confirmation, and plugin enumeration. All phases execute without authentication.
pip install ldap3
python3 poc/021-cleanruv-filter-injection.py <host> [port]
PoC 2: Pre-Auth Recon
Lightweight PoC demonstrating the BER payload construction and oracle concept. Supports offline demonstration mode (no server required) and live testing.
python3 poc/021-preauth-recon.py # offline demo
python3 poc/021-preauth-recon.py <host> # live test
Extractable Information
The oracle enables extraction of 31 configuration attributes from cn=config pre-auth, including:
| Attribute | Attack Value |
|---|---|
nsDS5ReplicaBindDN | Replication bind DN, target for credential attacks |
nsslapd-rootdn | Directory Manager username |
passwordStorageScheme | Hash algorithm, determines brute-force viability |
nsslapd-localhost | Server hostname |
nsslapd-certdir | Certificate directory path |
nsslapd-suffix | Database suffix (DIT structure) |
nsslapd-localuser | OS user running ns-slapd |
aci | ACI rule keywords (access control posture) |
nsslapd-pluginpath | Plugin .so names |
Password hash values (nsslapd-rootpw) and replication credentials (nsds5ReplicaCredentials) can be detected via presence checks but resist substring extraction due to their attribute syntax definitions.
Impact
CVSS 3.1: 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
| Component | Value | Justification |
|---|---|---|
| AV | Network | Triggered via LDAP protocol (ports 389/636) over TCP |
| AC | Low | Deterministic code path; filter passed through without validation |
| PR | None | Handler has zero auth checks; anonymous bind suffices with default config |
| UI | None | No user interaction required |
| S | Unchanged | Impact limited to the directory server’s configuration data |
| C | High | Complete read access to 31 string-syntax cn=config attributes via plugin identity (bypassing ACLs) |
| I | None | Injected filter is used in read-only search; no write operations |
| A | None | Search does not cause resource exhaustion or crash |
Exploit Chain
The oracle enables a multi-step attack against replication infrastructure:
- Pre-auth replication detection:
(nsDS5ReplicaId=*)confirms replication is configured - Pre-auth bind DN extraction: extract
nsDS5ReplicaBindDNcharacter by character (~60 requests, ~2 seconds) - Pre-auth password scheme detection: extract
passwordStorageSchemeto assess brute-force viability - Online password guessing (theoretical): target the extracted bind DN
- Replication channel access (theoretical): if step 4 succeeds, enables access to replication-channel vulnerabilities
Comparable CVEs
| CVE | Description | CVSS |
|---|---|---|
| CVE-2022-1949 | Access control bypass via filter optimizer; unauthenticated read of userPassword hashes | 7.5 |
| CVE-2020-35518 | Information disclosure during DN binding; unauthenticated DN existence check | 5.3 |
| CVE-2016-5416 | Default ACI readable by anonymous users; leakage of access control configuration | 7.5 |
Workaround
-
Disable anonymous access (most effective, raises PR from None to Low):
dn: cn=config changetype: modify replace: nsslapd-allow-anonymous-access nsslapd-allow-anonymous-access: rootdse -
Network segmentation: Restrict LDAP port access (389/636) to trusted networks.
-
Monitor for exploitation: Alert on
REPL_CLEANRUV_CHECK_STATUS_OIDextended operations:grep "EXT oid=\"2.16.840.1.113730.3.6.8\"" /var/log/dirsrv/slapd-<instance>/access -
Rotate replication credentials and use strong replication passwords.
Proposed Fix
Replace peer-supplied filter with server-side filter construction:
if (decode_cleanruv_payload(extop_payload, &replica_id)) {
goto free_and_return;
}
if (replica_id < 1 || replica_id > 65534) {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
"multisupplier_extop_cleanruv_check_status - "
"invalid replica ID: %d\n", replica_id);
goto free_and_return;
}
filter = slapi_ch_smprintf("(&(nsds5replicaid=%d)(objectclass=nstombstone))", replica_id);
Add replica_is_updatedn() authentication checks to all four CleanRUV handlers:
multisupplier_extop_cleanruv_check_status()(this finding)multisupplier_extop_cleanruv()multisupplier_extop_abort_cleanruv()multisupplier_extop_cleanruv_get_maxcsn()
Exploitation in the Wild
No evidence of exploitation in the wild was found.
Timeline
| Date | Event |
|---|---|
| 2026-04-15 | Discovered during 389-ds-base security assessment |
| 2026-04-22 | Full exploitation assessment completed |
| 2026-04-22 | Reported to vendor |
| 2026-07-07 | Public disclosure |
References
- Red Hat CVE page
- NVD
- CWE-90: LDAP Injection
- CWE-306: Missing Authentication for Critical Function
- CVE-2022-1949 (comparable): Filter optimizer ACL bypass
- CVE-2020-35518 (comparable): DN binding info disclosure
- 389-ds-base upstream repository
- CleanAllRUV Design
Credits
Discovered by Ian Murphy