LDAP injection via user input in search filter allows unauthorized access to directory entries
ID: security/ldap-injection-via-user-input-in-search-filter
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| OpenLDAP 2.6.6 | active | — | — | — |
| Microsoft Active Directory | active | — | — | — |
| Spring LDAP 2.4.0 | active | — | — | — |
| Python ldap3 2.9.1 | active | — | — | — |
Root Cause
The application constructs an LDAP search filter by concatenating user-supplied input without sanitization, allowing an attacker to inject LDAP metacharacters (e.g., *, |, &) to modify the filter logic and retrieve unauthorized data.
generic中文
应用程序通过拼接用户提供的输入来构建 LDAP 搜索过滤器,而未进行清理,允许攻击者注入 LDAP 元字符(如 *、|、&)来修改过滤器逻辑并检索未经授权的数据。
Official Documentation
https://owasp.org/www-community/attacks/LDAP_InjectionWorkarounds
-
92% success Use a dedicated LDAP encoding library to escape user input before constructing the filter. For Java, use `LdapName.escapeValue(input)` from Spring LDAP or `DefaultTemporaryDirectory` from Apache Directory API. Example: `String escapedInput = LdapName.escapeValue(userInput); String filter = "(&(uid=" + escapedInput + ")(objectClass=user))";`.
Use a dedicated LDAP encoding library to escape user input before constructing the filter. For Java, use `LdapName.escapeValue(input)` from Spring LDAP or `DefaultTemporaryDirectory` from Apache Directory API. Example: `String escapedInput = LdapName.escapeValue(userInput); String filter = "(&(uid=" + escapedInput + ")(objectClass=user))";`.
-
85% success Implement input validation to allow only alphanumeric characters and specific safe characters (e.g., email format). Reject any input containing LDAP metacharacters. Example regex for username: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`.
Implement input validation to allow only alphanumeric characters and specific safe characters (e.g., email format). Reject any input containing LDAP metacharacters. Example regex for username: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`. -
80% success Use a whitelist approach by mapping user input to predefined filter values. For example, if the input is a department name, map it to a safe list: `String filter = "(&(department=" + departmentMap.get(input) + ")(objectClass=user))";`.
Use a whitelist approach by mapping user input to predefined filter values. For example, if the input is a department name, map it to a safe list: `String filter = "(&(department=" + departmentMap.get(input) + ")(objectClass=user))";`.
中文步骤
使用专门的 LDAP 编码库在构建过滤器之前转义用户输入。对于 Java,使用 Spring LDAP 的 `LdapName.escapeValue(input)` 或 Apache Directory API 的 `DefaultTemporaryDirectory`。示例:`String escapedInput = LdapName.escapeValue(userInput); String filter = "(&(uid=" + escapedInput + ")(objectClass=user))";`。
实现输入验证,仅允许字母数字字符和特定安全字符(如电子邮件格式)。拒绝任何包含 LDAP 元字符的输入。用户名示例正则表达式:`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`。使用白名单方法,将用户输入映射到预定义的过滤器值。例如,如果输入是部门名称,则映射到安全列表:`String filter = "(&(department=" + departmentMap.get(input) + ")(objectClass=user))";`。
Dead Ends
Common approaches that don't work:
-
Use a blacklist to block common LDAP metacharacters like * and |
60% fail
Attackers can use alternative characters or encoding (e.g., URL encoding, Unicode) to bypass the blacklist. Blacklists are incomplete and not a robust defense.
-
Escape only parentheses and asterisks in user input
45% fail
LDAP injection can also use other metacharacters like &, !, =, ~, or null bytes. Incomplete escaping leaves vulnerabilities.
-
Use a stored procedure or prepared statement (as in SQL) for LDAP queries
80% fail
LDAP does not support prepared statements in the same way as SQL. Parameterized queries are not available in most LDAP libraries, so this approach is not applicable.