用户输入在搜索过滤器中导致 LDAP 注入,允许未经授权访问目录条目
LDAP injection via user input in search filter allows unauthorized access to directory entries
ID: security/ldap-injection-via-user-input-in-search-filter
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| OpenLDAP 2.6.6 | active | — | — | — |
| Microsoft Active Directory | active | — | — | — |
| Spring LDAP 2.4.0 | active | — | — | — |
| Python ldap3 2.9.1 | active | — | — | — |
根因分析
应用程序通过拼接用户提供的输入来构建 LDAP 搜索过滤器,而未进行清理,允许攻击者注入 LDAP 元字符(如 *、|、&)来修改过滤器逻辑并检索未经授权的数据。
English
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.
官方文档
https://owasp.org/www-community/attacks/LDAP_Injection解决方案
-
使用专门的 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))";`。
无效尝试
常见但无效的做法:
-
Use a blacklist to block common LDAP metacharacters like * and |
60% 失败
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% 失败
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% 失败
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.