Apache Zeppelin: LDAP search filter query Injection Vulnerability
Description
Apache Zeppelin 0.8.2 to 0.11.0 has an LDAP search filter injection vulnerability due to improper input validation, allowing attackers to execute malicious queries.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Apache Zeppelin 0.8.2 to 0.11.0 has an LDAP search filter injection vulnerability due to improper input validation, allowing attackers to execute malicious queries.
Vulnerability
Overview
CVE-2024-31867 is a high-severity improper input validation vulnerability in Apache Zeppelin's LDAP realm implementation. Affecting versions from 0.8.2 up to (but not including) 0.11.1, the flaw stems from the lack of sanitization of user-configurable LDAP search filter properties. Specifically, functions like setUserSearchFilter and setGroupSearchFilter directly assign user-supplied filter strings without escaping special characters that have meaning in LDAP filters as defined by RFC 4514 [1][3].
Attack
Vector and Prerequisites
An attacker with the ability to set Zeppelin configuration properties—typically through administrative access or via configuration files—can inject arbitrary LDAP filter syntax. By crafting malicious input containing characters such as *, |, &, !, =, ~, <, >, or parentheses, the attacker can modify the intended search filter logic. The injection occurs at the LDAP query level during authentication or search operations, requiring that Zeppelin is configured to use an LDAP realm [2][4]. No network-level exploits are necessary; the vulnerability is purely configurational.
Impact
Successful exploitation allows an attacker to execute arbitrary LDAP queries against the backend directory service. This can lead to unauthorized data access, privilege escalation (e.g., by bypassing authentication checks), or information disclosure by modifying filter predicates. In the worst case, an attacker could enumerate all users or groups, potentially gaining administrative credentials or accessing sensitive records stored in the LDAP directory [1][2].
Mitigation
The vulnerability is fixed in Apache Zeppelin version 0.11.1. The patch introduces an escapeAttributeValue method that properly escapes special LDAP characters as per RFC 4514. The fix applies to both user and group search filter setters [1][3]. Users are strongly advised to upgrade to 0.11.1 or later. No workarounds are documented, but limiting configuration access to trusted administrators can reduce risk [2][4].
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.zeppelin:zeppelin-serverMaven | >= 0.8.2, < 0.11.1 | 0.11.1 |
Affected products
2Patches
165d0bcc1ee8e[HOTFIX] Escape Ldap search filters (#4714)
2 files changed · +84 −2
zeppelin-server/src/main/java/org/apache/zeppelin/realm/LdapRealm.java+71 −2 modified@@ -773,15 +773,15 @@ public String getUserSearchFilter() { } public void setUserSearchFilter(final String filter) { - this.userSearchFilter = (filter == null ? null : filter.trim()); + this.userSearchFilter = (filter == null ? null : escapeAttributeValue(filter.trim())); } public String getGroupSearchFilter() { return groupSearchFilter; } public void setGroupSearchFilter(final String filter) { - this.groupSearchFilter = (filter == null ? null : filter.trim()); + this.groupSearchFilter = (filter == null ? null : escapeAttributeValue(filter.trim())); } public boolean getUserLowerCase() { @@ -941,6 +941,75 @@ userSearchAttributeName, expandTemplate(getUserSearchAttributeTemplate(), } } + // Implements the necessary escaping to represent an attribute value as a String as per RFC 4514. + // https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/realm/JNDIRealm.java#L2921 + protected String escapeAttributeValue(String input) { + if (input == null) { + return null; + } + int len = input.length(); + StringBuilder result = new StringBuilder(); + + for (int i = 0; i < len; i++) { + char c = input.charAt(i); + switch (c) { + case ' ': { + if (i == 0 || i == (len - 1)) { + result.append("\\20"); + } else { + result.append(c); + } + break; + } + case '#': { + if (i == 0) { + result.append("\\23"); + } else { + result.append(c); + } + break; + } + case '\"': { + result.append("\\22"); + break; + } + case '+': { + result.append("\\2B"); + break; + } + case ',': { + result.append("\\2C"); + break; + } + case ';': { + result.append("\\3B"); + break; + } + case '<': { + result.append("\\3C"); + break; + } + case '>': { + result.append("\\3E"); + break; + } + case '\\': { + result.append("\\5C"); + break; + } + case '\u0000': { + result.append("\\00"); + break; + } + default: + result.append(c); + } + } + + return result.toString(); + } + + @Override protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, Object ldapPrincipal, Object ldapCredentials, LdapContext ldapContext)
zeppelin-server/src/test/java/org/apache/zeppelin/realm/LdapRealmTest.java+13 −0 modified@@ -119,6 +119,19 @@ void testRolesFor() throws NamingException { assertEquals(new HashSet<>(Arrays.asList("group-one", "zeppelin-role")), roles); } + @Test + void testFilterEscaping() { + LdapRealm realm = new LdapRealm(); + assertEquals("foo", realm.escapeAttributeValue("foo")); + assertEquals("foo\\2B", realm.escapeAttributeValue("foo+")); + assertEquals("foo\\5C", realm.escapeAttributeValue("foo\\")); + assertEquals("foo\\00", realm.escapeAttributeValue("foo\u0000")); + realm.setUserSearchFilter("uid=<{0}>"); + assertEquals("uid=\\3C{0}\\3E", realm.getUserSearchFilter()); + realm.setUserSearchFilter("gid=\\{0}\\"); + assertEquals("gid=\\5C{0}\\5C", realm.getUserSearchFilter()); + } + private NamingEnumeration<SearchResult> enumerationOf(BasicAttributes... attrs) { final Iterator<BasicAttributes> iterator = Arrays.asList(attrs).iterator(); return new NamingEnumeration<SearchResult>() {
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/apache/zeppelin/pull/4714ghsapatchWEB
- github.com/advisories/GHSA-qmr3-52xf-wmhxghsaADVISORY
- lists.apache.org/thread/s4scw8bxdhrjs0kg0lhb68xqd8y9lrtfghsavendor-advisoryWEB
- nvd.nist.gov/vuln/detail/CVE-2024-31867ghsaADVISORY
- www.openwall.com/lists/oss-security/2024/04/09/12ghsaWEB
- github.com/apache/zeppelin/commit/65d0bcc1ee8ec3ec372d0a71ab513cd20e6522a0ghsaWEB
News mentions
0No linked articles in our index yet.