CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-23906
9.80.03%

The Ghost in the LDAP: Apache Druid Authentication Bypass

Amit Schendel
Amit Schendel
Senior Security Researcher

Feb 10, 2026·6 min read·23 visits

PoC Available

Executive Summary (TL;DR)

If you use LDAP for Apache Druid authentication and your LDAP server allows anonymous binds (a common default), anyone can log in as 'admin' by sending an empty password. CVSS 9.8. Upgrade to 36.0.0 immediately or disable anonymous binds in LDAP.

Apache Druid, the high-performance real-time analytics database, has dropped the ball on basic authentication logic. By failing to differentiate between an 'anonymous' LDAP bind and a 'user' LDAP bind, Druid allows attackers to log in as any user—including administrators—simply by providing an empty password. This is a classic protocol confusion vulnerability that turns a misconfigured LDAP server into a golden key for your data warehouse.

The Hook: Trust Issues

In the world of high-speed analytics, Apache Druid is the muscle car. It ingests massive streams of event data and lets you query it with sub-second latency. But like a muscle car with no door locks, speed doesn't matter if someone can just hop in and drive it off a cliff.

CVE-2026-23906 is what happens when a developer trusts a protocol response a little too much. It resides in the druid-basic-security extension, specifically the LDAP authenticator. This component is responsible for taking a username and password from the web console, passing it to your corporate LDAP/Active Directory, and asking, "Is this guy legit?"

The problem isn't that Druid fails to ask the question. The problem is that it misunderstands the answer. It’s the digital equivalent of a bouncer asking a club owner, "Is the club open to the public?" and when the owner says "Yes," the bouncer assumes the random guy in the hoodie is the VIP on the guest list.

The Flaw: The Anonymous Bind Trap

To understand this vulnerability, you have to understand a quirk of the LDAP protocol that has plagued sysadmins since the 90s: the Anonymous Bind.

In LDAP (Lightweight Directory Access Protocol), a client initiates a session by sending a 'Bind Request'. This request usually contains a Distinguished Name (DN) and a password. However, the protocol spec allows for an 'unauthenticated' state. If a client sends a Bind Request with a DN but an empty password (length zero), the server interprets this not as a login attempt for that specific user, but as a request for an anonymous session.

If the LDAP server is configured to allow anonymous access (which, terrifyingly, is the default in many older OpenLDAP configs and some Active Directory setups for compatibility), it returns LDAP_SUCCESS (Code 0).

Here is where Druid trips over its own shoelaces. The authentication logic flows like this:

  1. User submits admin and "" (empty string).
  2. Druid passes this to the LDAP context.
  3. LDAP Server sees empty password -> switches to Anonymous Bind -> returns Success.
  4. Druid sees Success and thinks, "Great! The password for admin was correct!"
  5. Druid grants the session the privileges of admin.

Druid essentially confuses "The server allowed a connection" with "The user proved their identity."

The Code: Logic Errors in Java

While the exact patch involves specific Druid internal classes, the vulnerability pattern is textbook Java JNDI misuse. Let's look at a reconstruction of the vulnerable logic versus the secure implementation.

The Vulnerable Logic

The code creates an InitialDirContext using the credentials provided by the user. If the constructor doesn't throw an exception, the code assumes authentication succeeded.

// VULNERABLE PSEUDO-CODE
public boolean authenticate(String userDn, String password) {
    Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, ldapUrl);
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, userDn);
    // FATAL FLAW: No check for empty password here
    env.put(Context.SECURITY_CREDENTIALS, password);
 
    try {
        // If this succeeds, Druid assumes the userDN matches the password.
        // But if password is "", LDAP returns success for Anonymous!
        DirContext ctx = new InitialDirContext(env);
        ctx.close();
        return true;
    } catch (NamingException e) {
        return false;
    }
}

The Fix

The fix is embarrassingly simple: Do not attempt to bind if the password is empty. Alternatively, explicitly disable anonymous pools in the connection config, but the explicit check is safer at the application level.

// PATCHED LOGIC
public boolean authenticate(String userDn, String password) {
    // THE FIX: Explicitly reject empty passwords
    if (password == null || password.trim().isEmpty()) {
        LOG.warn("Auth failed: Empty password provided for user " + userDn);
        return false;
    }
 
    Properties env = new Properties();
    // ... rest of the setup ...
    try {
        DirContext ctx = new InitialDirContext(env);
        return true;
    } catch (NamingException e) {
        return false;
    }
}

It is a simple if statement that stands between your data and the internet.

The Exploit: Becoming Admin

Exploiting this is trivial. You don't need a buffer overflow, you don't need a heap spray, and you don't need complex gadgets. You just need curl and a lack of morals.

Step 1: Reconnaissance

First, identify an Apache Druid instance. They typically listen on ports 8081 (Coordinator) or 8888 (Router). If the druid-basic-security extension is on, you'll be greeted with a login prompt.

Step 2: Identification

You need a valid username. admin is the default hardcoded user in many setups. druid is another common one. If you can enumerate users (via a different leak or guessing common names like jdoe), you can impersonate them.

Step 3: The Attack

Capture the login request (usually a POST to /druid-ext/basic-security/authentication/db/basic/login or similar, depending on the exact auth provider mapping). Replay it with an empty password.

# The "Hacker" Command
curl -i -X POST https://target-druid:8888/druid/v2/login \
     -H "Content-Type: application/json" \
     -d '{"username": "admin", "password": ""}'

Step 4: The Result

If the backend LDAP allows anonymous binds:

HTTP/1.1 200 OK
Set-Cookie: druid.session=eyJhbGciOiJIUzI1NiJ9...; Path=/; HttpOnly
Content-Type: application/json
 
{"user": "admin", "roles": ["admin"]}

Boom. You now have a session cookie for the admin user. You can now access the Druid console, drop tables, or submit malicious ingestion tasks that could lead to Remote Code Execution (RCE) on the cluster nodes.

The Impact: Why This Matters

Druid isn't just a database; it's a distributed system often running with significant privileges to access cloud storage (S3, GCS) and HDFS.

1. Full Data Compromise: An attacker can query all data. In many organizations, Druid holds aggregated, sensitive business intelligence data.

2. Data Destruction: With admin access, an attacker can mark segments as 'unused', effectively deleting petabytes of historical data instantly.

3. Potential RCE: This is the scary part. Druid allows 'Ingestion Specs'. These are JSON instructions on how to load data. While Druid has sandboxing, a privileged user can often configure ingestion tasks to read files from the local filesystem of the detailed nodes, or use JDBC lookups to attack internal databases. In some configurations, Java-based ingestion tasks or JavaScript functions (if enabled) can lead to full Remote Code Execution.

The Fix: Closing the Door

You have two options: fix the application or fix the infrastructure. Do both.

1. Upgrade Druid (The Real Fix)

Apache Druid version 36.0.0 introduces the check for empty passwords. Upgrade immediately. This ensures that even if your LDAP server is promiscuous, Druid won't take the bait.

2. Configure LDAP (The Safety Net)

Why does your LDAP server allow anonymous binds in 2026? Stop that.

  • OpenLDAP: Set disallow bind_anon in your slapd.conf.
  • Active Directory: Ensure the DsHeuristics attribute is set to disable anonymous access (though AD usually disables this by default on newer forests, legacy setups drift).

This is a classic 'Defense in Depth' scenario. The application shouldn't be vulnerable, but the infrastructure shouldn't be permissive.

Official Patches

ApacheOfficial 36.0.0 Release

Fix Analysis (1)

Technical Appendix

CVSS Score
9.8/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
EPSS Probability
0.03%
Top 92% most exploited

Affected Systems

Apache Druid 0.17.0 through 35.xDruid clusters using druid-basic-security extensionDruid clusters configured with LDAP authentication

Affected Versions Detail

Product
Affected Versions
Fixed Version
Apache Druid
Apache
>= 0.17.0, < 36.0.036.0.0
AttributeDetail
CWE IDCWE-287 (Improper Authentication)
Attack VectorNetwork
CVSS9.8 (Critical)
ImpactFull Admin Access / Potential RCE
EPSS Score0.03%
Exploit StatusTrivial / Conceptual

MITRE ATT&CK Mapping

T1078Valid Accounts
Initial Access
T1586Compromise Accounts
Resource Development
CWE-287
Improper Authentication

Known Exploits & Detection

ManualManual exploitation via HTTP POST with empty password field

Vulnerability Timeline

Vulnerability Disclosed
2026-02-10
Patch 36.0.0 Released
2026-02-10

References & Sources

  • [1]Apache Security Mailing List

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.