LDAP Injection in CMAK (Cluster Manager for Apache Kafka) via Search Filter

Open Beginner friendly
#8,841 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
scala

Research direction

Start with app/controllers/BasicAuthenticationFilter.scala and inspect renderSearchFilter() around line 264, then review how the username enters the LDAP search filter. Validate the reported special-character cases against the affected versions; done means user input is safely escaped before insertion and the listed injection vectors no longer change the filter meaning.

Written by the indexing model from the issue text.

Description

Summary

Yahoo CMAK (Cluster Manager for Apache Kafka) versions up to and including 3.0.0.6 are vulnerable to LDAP Injection (CWE-90) in the LDAP authentication module.

Vulnerability Details

File: app/controllers/BasicAuthenticationFilter.scala
Function: renderSearchFilter() at line 264
Root Cause: User-supplied username is inserted into LDAP search filter via simple string replacement (%s) without LDAP special character escaping.

Vulnerable Code (line 264):
private def renderSearchFilter(username: String): String = {
  searchFilter.replaceAll("%s", username)
}

The function passes raw user input directly into an LDAP search filter string. LDAP metacharacters such as *, (, ), \, and NUL byte are not escaped before insertion.

Attack Vectors

An attacker can inject LDAP filter syntax through the HTTP Basic Authentication username field:

  1. Wildcard bypass (*): Matches any LDAP entry, bypassing username validation
  2. Boolean logic injection (admin)(|(cn=*)): Injects OR conditions to match arbitrary entries
  3. Filter manipulation (*)(objectClass=*)): Extends filter to match all objects
  4. Attribute enumeration (*)(mail=*@yahoo.com)): Enumerates entries by attribute

Impact

  • Authentication bypass: Attacker can log in as any LDAP user without knowing the password (if LDAP bind is not configured)
  • LDAP data exfiltration: Enumeration of LDAP directory entries (usernames, emails, group memberships)
  • Authorization escalation: Access admin-level CMAK functions (topic deletion, partition reassignment, broker configuration)

Proof of Concept

A complete Docker-based PoC is available demonstrating 4 confirmed attack vectors against a live CMAK + OpenLDAP setup:

# Attack vector: wildcard authentication bypass
import requests, base64

target = "http://cmak-host:9000/"
# Normal user "admin" → 401 without correct password
# Wildcard "*" → matches all LDAP entries → bypass
cred = base64.b64encode(b"*:anything").decode()
r = requests.get(target, headers={"Authorization": f"Basic {cred}"})
# Returns 200 instead of 401

Recommended Fix

Replace renderSearchFilter with proper LDAP escaping:

import javax.naming.ldap.Rdn

private def renderSearchFilter(username: String): String = {
  searchFilter.replaceAll("%s", Rdn.escapeValue(username).toString)
}

This uses javax.naming.ldap.Rdn.escapeValue() which is part of the standard Java/Scala library and properly escapes all LDAP special characters including *, (, ), \, and NUL.

Dominant language
No language data
Stars
2.5k
Forks
772
Avg merge
3d 20h
Merged PRs (30d)
49

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from github/advisory-database

All issues in github/advisory-database

Similar issues

More Security issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.