What's the vulnerability?

Apache Druid basic security LDAP authenticator can be bypassed when the LDAP server allows anonymous binds, permitting login with any existing username and an empty password.

Root Cause Analysis

## Summary
Apache Druid’s druid-basic-security LDAP authenticator accepts a successful LDAP bind as proof of authentication without verifying that a password was actually supplied. If the backing LDAP server allows simple binds with an empty password (anonymous bind with DN), any existing username can be authenticated by providing an empty password.

## Impact
- **Package/component affected:** org.apache.druid.extensions:druid-basic-security (LDAPCredentialsValidator)
- **Affected versions:** >= 0.17.0, < 36.0.0 (verified on 35.0.0)
- **Risk level:** High – attackers can authenticate as any existing LDAP user with an empty password when the LDAP server allows anonymous bind, leading to unauthorized access to Druid APIs and data.

## Root Cause
LDAPCredentialsValidator#validateCredentials looks up the user DN using the configured bind user, then calls validatePassword() which performs a simple LDAP bind with the supplied password. The code treats any successful bind as valid credentials, but does not explicitly reject empty passwords. On LDAP servers configured to accept simple binds with an empty password (anonymous bind with DN), the bind succeeds and authentication is granted. The patched release (36.0.0) adds explicit checks to reject empty passwords before attempting LDAP bind.

## Reproduction Steps
1. Run `repro/reproduction_steps.sh`.
2. The script builds Druid 35.0.0, launches an in-memory LDAP server that accepts empty-password binds, then runs a Java PoC calling LDAPCredentialsValidator with username `alice` and an empty password.
3. Expected evidence: the script prints `AUTH_SUCCEEDED: alice` and `Vulnerability reproduced: LDAP anonymous bind accepted empty password`.

## Evidence
- Log file: `logs/poc_output.txt`
- Key excerpt:
  - `AUTH_SUCCEEDED: alice`
  - `Vulnerability reproduced: LDAP anonymous bind accepted empty password`
- Environment: OpenJDK 17, Maven build of Druid 35.0.0 with UnboundID in-memory LDAP server.

## Recommendations / Next Steps
- Add explicit validation to reject empty passwords before attempting LDAP bind (as done in 36.0.0).
- Upgrade to Apache Druid 36.0.0 or later.
- Add regression tests to ensure empty passwords are rejected even if LDAP accepts anonymous binds.

## Additional Notes
- The reproduction script is idempotent and verified to pass twice consecutively.
- The PoC uses a real LDAP server (UnboundID in-memory) configured to allow empty-password binds, matching the vulnerable behavior scenario.
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00087
or pruva-verify GHSA-Q672-HFC7-G833
or pruva-verify CVE-2026-23906
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00087/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available