{
  "id": "security/ldap-injection-via-user-input-in-search-filter",
  "signature": "LDAP injection via user input in search filter allows unauthorized access to directory entries",
  "signature_zh": "用户输入在搜索过滤器中导致 LDAP 注入，允许未经授权访问目录条目",
  "regex": "LDAP|search filter|injection|directory|bind",
  "domain": "security",
  "category": "data_error",
  "subcategory": null,
  "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.",
  "root_cause_type": "generic",
  "root_cause_zh": "应用程序通过拼接用户提供的输入来构建 LDAP 搜索过滤器，而未进行清理，允许攻击者注入 LDAP 元字符（如 *、|、&）来修改过滤器逻辑并检索未经授权的数据。",
  "versions": [
    {
      "version": "OpenLDAP 2.6.6",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Microsoft Active Directory",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Spring LDAP 2.4.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Python ldap3 2.9.1",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Use a blacklist to block common LDAP metacharacters like * and |",
      "why_fails": "Attackers can use alternative characters or encoding (e.g., URL encoding, Unicode) to bypass the blacklist. Blacklists are incomplete and not a robust defense.",
      "fail_rate": 0.6,
      "condition": "",
      "sources": []
    },
    {
      "action": "Escape only parentheses and asterisks in user input",
      "why_fails": "LDAP injection can also use other metacharacters like &, !, =, ~, or null bytes. Incomplete escaping leaves vulnerabilities.",
      "fail_rate": 0.45,
      "condition": "",
      "sources": []
    },
    {
      "action": "Use a stored procedure or prepared statement (as in SQL) for LDAP queries",
      "why_fails": "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.",
      "fail_rate": 0.8,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "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))\";`.",
      "success_rate": 0.92,
      "how": "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))\";`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "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,}$`.",
      "success_rate": 0.85,
      "how": "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,}$`.",
      "condition": "",
      "sources": []
    },
    {
      "action": "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))\";`.",
      "success_rate": 0.8,
      "how": "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))\";`.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "使用专门的 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))\";`。"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://owasp.org/www-community/attacks/LDAP_Injection",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.86,
  "fix_success_rate": 0.9,
  "resolvable": "true",
  "first_seen": "2024-05-20",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}