// Low (3.3)
CVE-2026-11792

Heap buffer overflow in audit log password masking

CVE ID
CVE-2026-11792
Product
389-ds-base
Severity
Low (3.3)
CVSS Vector
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L
CWE
CWE-122
Red Hat CVE
Red Hat CVE page

Summary

A heap buffer overflow exists in 389 Directory Server’s audit log password masking feature. When audit logging is enabled and a short cleartext password reaches the audit log via an LDAP ADD operation, the server writes a fixed-length mask string past the end of a precisely-sized heap buffer. Exploiting this requires non-default, explicitly discouraged configuration (cleartext password storage) or a compromised replication peer, making real-world impact low.

Affected Versions

ComponentVersionStatus
389-ds-base (upstream)3.2.0+ (post-commit bfeaa8d)Vulnerable (confirmed — source review)
389-ds-base (upstream)Pre-July 2025 (before Issue 6884)Not affected — create_masked_entry_string() does not exist
Fedora 43389-ds-base-3.1.4-7.fc43Vulnerable (confirmed — live server test)
Fedora 42389-ds-base-3.1.2-4.fc42Not affected — pre-dates Issue 6884 introduction
RHEL 10 / CentOS Stream 10389-ds-base-3.1.3-4.el10+Vulnerable (code present — RHEL-107035 backported the password masking feature)
RHEL 9.6389-ds-base-2.6.1-11.el9_6+Vulnerable (code present — RHEL-109954 backported the password masking feature)
RHEL 9.0 - 9.5389-ds-base-2.0.x - 2.5.xNot affected — pre-dates Issue 6884 backport
RHEL 8389-ds-base-1.4.xNot affected — create_masked_entry_string() does not exist in 1.4.x
RHEL 7389-ds-base-1.3.xNot affected — create_masked_entry_string() does not exist in 1.3.x
Red Hat Directory Server 12.6389-ds-base-2.6.xVulnerable (RHDS 12.6 = RHEL 9.6 AppStream; same 2.6.1-11 backport)
Red Hat IdM (RHEL 9.6+)Depends on 389-ds-baseVulnerable (IdM/FreeIPA uses 389-ds-base as its LDAP backend)
Red Hat IdM (RHEL 10)Depends on 389-ds-baseVulnerable (IdM/FreeIPA uses 389-ds-base as its LDAP backend)

Version boundary: The vulnerable function create_masked_entry_string() was introduced upstream by commit bfeaa8d (Issue 6884, PR #6885) in July 2025 and first shipped in upstream releases 2.8.0 and 3.2.0. It was backported to RHEL 9.6 (RHBA-2025:15534) and RHEL 10 (389-ds-base-3.1.3-4.el10) as a fix for CWE-532 (password hashes visible in audit logs).

Architecture note: This vulnerability is architecture-independent. The overflow is a fixed-size strcpy of 24 bytes into a variable-size buffer slot determined by the password value length. No pointer size, alignment, or endianness factors affect triggering. Confirmed on aarch64 (ASan PoC on macOS arm64e and Fedora 42 aarch64).

Root Cause

File: ldap/servers/slapd/auditlog.c:109 Function: create_masked_entry_string() Verified against: 389-ds-base source at commit b019653 on test system, 2026-04-22

The create_masked_entry_string() function masks password attribute values in audit log entries for LDAP ADD operations. It receives a buffer from slapi_entry2str() that is allocated with exact sizing (no padding or slack), then iterates through the LDIF lines looking for password attributes:

/* auditlog.c line 108-110 */
if (is_password_attribute(line_start)) {
    strcpy(colon_pos + 1, " **********************");  /* 23 bytes + NUL = 24 bytes */
}

The mask string is 23 characters plus a NUL terminator (24 bytes total). If the password value after the colon is shorter than 23 characters, the strcpy writes past the allocated buffer boundary. For example, userPassword: x has 2 bytes after the colon (" x"), but strcpy writes 24 bytes, overflowing 22 bytes past the value position.

The buffer comes from slapi_entry2str() (entry.c:1658), which computes elen by summing the exact byte counts of all attributes and allocates via slapi_ch_malloc(elen) with no padding.

Why only ADD operations are affected: The MODIFY path (auditlog.c:836-842) uses addlenstr(), which dynamically grows the buffer. The ADD path (auditlog.c:864-877) calls create_masked_entry_string(), which modifies the exactly-sized buffer in-place.

Why cleartext passwords are required: For non-replicated ADDs, pw_encodevals_ext() (add.c:679) hashes the password before the audit log runs, producing ~450-char values that are always longer than the 23-byte mask. For replicated ADDs (repl_op=1), the hashing branch (add.c:641-693) is entirely skipped (add.c:628-640), so the password retains whatever value the replication supplier sent.

All line numbers verified against actual source on test system at /home/user/src/389-ds-base-src/ on 2026-04-22. strcpy at line 109 confirmed. ADD path create_masked_entry_string call at line 868 confirmed. repl_op branch at add.c:628-640 confirmed.

Proof of Concept

PoC source code: CVE-2026-11792 on GitHub

Standalone ASan PoC

The file poc/poc_006_auditlog_repl.c is a self-contained reproduction of the vulnerable create_masked_entry_string() function. It simulates the exact buffer allocation behavior of slapi_entry2str() and triggers the overflow with a 1-byte cleartext password.

Compile and run:

gcc -fsanitize=address -g -o poc_006 poc/poc_006_auditlog_repl.c
./poc_006

Expected result: ASan reports heap-buffer-overflow with WRITE of size 24:

==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x...00cd
WRITE of size 24 at 0x...00cd thread T0
    #0 ... in strcpy/memcpy
    #1 ... in create_masked_entry_string poc_006_auditlog_repl.c:101
0x...00cd is located 0 bytes after 141-byte region [0x...0040,0x...00cd)

Live server test (audit log corruption)

  1. Deploy a 389-ds-base supplier-consumer replication topology.
  2. Enable audit logging on both instances:
    dsconf slapd-supplier config replace nsslapd-auditlog-logging-enabled=on
    dsconf slapd-consumer config replace nsslapd-auditlog-logging-enabled=on
  3. Set cleartext password storage on the supplier:
    dsconf slapd-supplier config replace passwordStorageScheme=CLEAR
  4. Add a user with a short password:
    ldapadd -x -H ldap://localhost:389 -D "cn=Directory Manager" -w <password> <<EOF
    dn: uid=overflow006,ou=customers,dc=dapperdan,dc=com
    objectClass: inetOrgPerson
    uid: overflow006
    cn: Overflow Test
    sn: Test
    userPassword: x
    EOF
  5. Expected result: Both supplier and consumer audit logs show corrupted output:
    userPassword: *****
    ****************
    The 23-byte mask overflows past the 1-byte cleartext value. Neither instance crashes (production binary without ASan absorbs the 22-byte overflow in allocator padding), but heap memory is corrupted.

Supporting evidence files

FileDescription
poc/poc_006_auditlog_repl.cFull PoC source (197 lines, includes diagnostic output)
poc/asan-trace-006-local.txtASan trace from macOS arm64e
poc/asan-trace-006-container.txtASan trace from Fedora 42 aarch64
poc/auditlog-testA-supplier-pbkdf2.logLive server audit log — PBKDF2 default, no overflow
poc/auditlog-testB-supplier-clear.logLive server audit log — CLEAR scheme, overflow on supplier
poc/auditlog-testB-consumer-clear.logLive server audit log — CLEAR scheme, overflow on consumer via replication

Impact

CVSS 3.1: 3.3 (Low) — CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:L

ComponentValueJustification
AV (Attack Vector)NetworkReplication is network-based; LDAP ADD is network-accessible
AC (Attack Complexity)HighRequires non-default passwordStorageScheme: CLEAR (explicitly discouraged) or a compromised replication peer, AND audit logging enabled (also non-default). Two non-default prerequisites must coincide.
PR (Privileges Required)HighAdmin privileges to configure CLEAR scheme; replication manager credentials for compromised peer scenario
UI (User Interaction)NoneNo user interaction required once configuration is in place
S (Scope)UnchangedImpact limited to the ns-slapd process
C (Confidentiality)NoneNo data disclosed by the overflow itself
I (Integrity)LowAudit log output is corrupted (mask overwrites adjacent data in the log buffer); heap metadata may be corrupted
A (Availability)LowHeap corruption may cause crash on subsequent allocations/frees; confirmed abort on ASan builds. Production builds absorbed the overflow in allocator padding during testing, but this is not guaranteed.

Primary impact: The ns-slapd LDAP server process. The heap corruption occurs in a transient logging allocation that is freed immediately after use (slapi_ch_free at auditlog.c:877).

Downstream consumers of 389-ds-base:

ConsumerRelationshipImpact
Red Hat IdM / FreeIPAUses 389-ds-base as its LDAP backendIf IdM enables audit logging with CLEAR scheme, the IdM LDAP backend process is affected. IdM does not use CLEAR scheme by default.
Red Hat Directory Server (RHDS) 12.xDirect packaging of 389-ds-baseSame impact as upstream. RHDS documentation discourages CLEAR scheme.
Dogtag Certificate SystemUses 389-ds-base for its internal LDAP storeDogtag does not store user passwords in CLEAR scheme. Not affected in practice.
SSSD / pam_ldap clientsConnect to 389-ds-base as LDAP clientsNot directly affected — the overflow is in the server process, not clients. If the server crashes due to heap corruption, clients lose connectivity (DoS).

Replication topology impact: In a multi-supplier topology, if one instance crashes due to heap corruption, replication continues between surviving instances. The crashed instance resumes replication after restart. No data loss expected from the overflow itself.

No evidence of exploitation in the wild. The create_masked_entry_string() function was introduced in July 2025 (less than 1 year ago). The passwordStorageScheme: CLEAR configuration is explicitly discouraged in 389-ds-base documentation and disabled by default.

Comparable CVEs:

CVEBug classCVSSNotes
CVE-2024-1062Heap overflow in log_entry_attr() (same file, different function)5.5 (Medium)Values > 256 chars overflowing a fixed buffer; local attack vector, low complexity. This finding has higher complexity (non-default config) and network vector.
CVE-2025-14905Heap overflow in schema_attr_enum_callback()7.2 (Medium)Different function in schema.c; RCE potential with lower prerequisites. This finding has lower impact (fixed overflow content, transient buffer).
CVE-2017-2591OOB heap read in attribute uniqueness pluginLowDoS via segfault; different bug class (read vs write).

Workaround

  1. Do not use passwordStorageScheme: CLEAR. The default PBKDF2-SHA512 produces password hashes longer than 23 characters, preventing the overflow. This is the primary and most effective workaround.

  2. If CLEAR scheme is required for testing, disable audit logging during the test window:

    dsconf slapd-<instance> config replace nsslapd-auditlog-logging-enabled=off
  3. Monitor replication agreements for unauthorized peers. A compromised replication partner could send crafted ADD operations with short cleartext passwords that bypass password hashing on the consumer.

  4. Do not enable audit logging unless required. Audit logging is non-default. If it is not needed for compliance or operational requirements, leaving it disabled eliminates this attack surface entirely.

Proposed Fix

Replace the unsafe strcpy with a bounded copy that respects the available space in the buffer:

if (is_password_attribute(line_start)) {
    const char *mask = " **********************";
    size_t mask_len = strlen(mask);
    size_t avail = 0;

    /* Calculate available space from colon_pos+1 to end of value */
    if (next_line != NULL) {
        avail = (size_t)(next_line - (colon_pos + 1));
    } else {
        avail = strlen(colon_pos + 1);
    }

    if (mask_len <= avail) {
        memcpy(colon_pos + 1, mask, mask_len);
        /* NUL-fill remaining space to avoid leaking original value */
        memset(colon_pos + 1 + mask_len, ' ', avail - mask_len);
    } else {
        /* Mask is longer than available space -- truncate mask */
        memcpy(colon_pos + 1, mask, avail);
    }
}

Alternatively, use a dynamically-growing buffer (like the MODIFY path’s addlenstr()) instead of in-place modification of the exactly-sized slapi_entry2str() buffer. This approach would also fix the related data truncation bug where the strcpy NUL terminator truncates subsequent LDIF content for long hashed passwords.

Timeline

DateEvent
2026-04-14Discovered during 389-ds-base security assessment
2026-04-15Reported to vendor

References

Credits

Discovered by Ian Murphy.