What Is LDAP Injection?
LDAP injection is an injection weakness where application input is interpreted as LDAP query syntax rather than only as data. LDAP is commonly used for identity directories, employee lookup, group membership and authentication, so a vulnerable filter can affect both confidentiality and access control.
MITRE tracks this as CWE-90. OWASP emphasizes that LDAP distinguished names and LDAP search filters have different escaping rules; using the wrong encoder can leave a query unsafe even when the application believes it has “sanitized” input.
How LDAP Filter Injection Happens
A typical vulnerable pattern builds a search filter by concatenating a username or another request parameter into a filter string. If special filter characters are accepted without LDAP filter encoding, the input can change the expression.
// Unsafe concept: query structure and data are mixed
filter = "(&(uid=" + username + ")(active=true))";
// Safer concept: keep structure fixed and encode the value
filter = "(&(uid=" + escapeLDAPFilter(username) + ")(active=true))";The safe encoder must implement the rules for the exact LDAP context. HTML escaping, URL encoding and SQL escaping are not substitutes for LDAP filter encoding.
LDAP Injection and Authentication Bypass
Authentication code can be vulnerable when it first searches for a directory object using an unsafe filter and then treats a successful match as proof of identity. An attacker does not need to “break LDAP” itself; changing the search logic may be enough to make the application select an unintended user or broaden the result set.
LDAP Filter Escaping vs Distinguished Name Escaping
| Context | What it represents | Security requirement |
|---|---|---|
| LDAP search filter | Predicates that select directory entries | Use RFC 4515-compatible filter value escaping |
| Distinguished Name (DN) | The name/path of a directory object | Use RFC 4514-compatible DN escaping |
| Application validation | Expected username/group/input format | Allowlist business-valid characters and length where practical |
Do not reuse one “LDAP sanitize” helper everywhere. The correct encoding depends on whether the value is placed in a search filter or in a distinguished name.
LDAP Filter Construction Examples
Prefer libraries or frameworks that perform LDAP encoding for the appropriate context. Where applications must construct filters, build a fixed filter template and encode each external value before insertion.
function findUser(username) {
const safeUser = ldapFilterEncode(username);
const filter = `(&(uid=${safeUser})(accountStatus=active))`;
return directory.search(BASE_DN, filter);
}The filter structure should remain application-controlled, while each external value is encoded for the LDAP search-filter context before insertion. Also verify that authentication lookup logic returns exactly the intended account rather than accepting a broad or ambiguous result set.
LDAP Authentication: Search-Then-Bind and Empty-Password Pitfalls
LDAP-backed login often has two separate operations: locate the intended directory entry, then verify credentials by binding as that identity or through another approved authentication mechanism. Keeping those steps explicit makes it easier to enforce that a lookup returns exactly one expected account before any authentication result is accepted.
OWASP also calls out an easily missed edge case: applications using name/password bind authentication should reject an empty password before the bind. In some LDAP configurations, a non-empty name with an empty password can result in an unauthenticated or anonymous authorization state. A successful protocol operation in that situation must not be interpreted as proof that the user supplied valid credentials.
Authenticated bind does not fix an unsafe search filter. If the application constructs the lookup expression from external input, apply the correct RFC 4515 search-filter encoding even when the directory connection itself is authenticated. Distinguished-name values use different RFC 4514 escaping rules.
LDAP Injection Prevention Guide
- Use an LDAP-specific encoder for every untrusted value inserted into a search filter.
- Use the separate, correct encoder for values inserted into distinguished names.
- Prefer directory/framework APIs that handle escaping automatically and document the behavior.
- Allowlist expected usernames, group names and attribute values where business rules permit it.
- Run directory searches with least-privileged service accounts.
- Require exact, unambiguous results in authentication and authorization workflows.
- Keep directory errors and filter strings out of client-facing responses and logs accessible to untrusted users.
LDAP Search Scope, Result Cardinality and Least Privilege
Correct escaping protects query structure, but authentication logic also needs strict expectations about where the search runs and how many directory entries may satisfy it. Constrain the search base and scope to the intended organizational unit, use fixed attribute names, and fail closed when a login lookup returns zero or more than one eligible identity.
Do not let external input choose LDAP attribute names, search bases or filter fragments simply because individual values are encoded. Those elements are query structure and should normally come from application configuration or an allowlist.
The directory account used for lookup should have only the permissions the application needs. Least privilege does not prevent LDAP injection, but it limits what an injected query can read or modify if another control fails. Authentication, group lookup and write operations should not automatically share one broadly privileged bind account.
How to Test LDAP Injection in a Controlled Environment
Code review should locate every dynamic LDAP filter and DN construction site. Confirm that input is encoded in the correct LDAP context and that authentication logic handles zero, one and multiple matches securely.
Validation testing should confirm that LDAP metacharacters remain data, that zero/multiple-result conditions fail closed, and that authentication never succeeds because a directory operation fell back to anonymous behavior.
Authentication Failure Modes to Test
LDAP-backed authentication should fail closed across more conditions than an obviously malformed filter. Test empty passwords, missing accounts, duplicate or ambiguous directory matches, disabled accounts, directory timeouts and lookup failures. None of these conditions should be transformed into a successful or anonymous application session.
Keep error details out of the client response. A login endpoint usually does not need to reveal whether the username was absent, the password was wrong, a group lookup failed or the directory service was temporarily unavailable. Internally, preserve enough structured telemetry to distinguish configuration failures from suspicious input and repeated authentication probing.
LDAP Injection in APIs and Identity Integrations
APIs that proxy directory search, employee lookup, group membership or legacy authentication can expose LDAP injection even when the public interface is JSON or REST. Input type validation at the API boundary reduces ambiguity, but the directory query still needs LDAP-specific encoding at the sink.
Related Ammune reading: API authorization vs authentication and OWASP broken API authentication and API SQL injection testing guide.
Runtime Visibility Around Directory-Backed APIs
Ammune can help teams identify abnormal request patterns and repeated injection-like inputs reaching directory-backed APIs. It complements, but does not replace, safe LDAP query construction and least-privileged directory access.
LDAP Injection Defense Checklist
- Inventory LDAP search filters and DN construction in authentication and admin code.
- Use context-correct LDAP encoders, not generic escaping.
- Keep filter syntax fixed and values separate.
- Validate expected usernames and directory attributes.
- Use least-privileged LDAP service accounts.
- Reject ambiguous authentication results.
- Add regression tests for LDAP metacharacters.
- Monitor directory-backed APIs for repeated malformed filter input.
Frequently Asked Questions
What is LDAP injection?
LDAP injection occurs when untrusted input changes LDAP query syntax instead of remaining a value.
Can LDAP injection bypass authentication?
Yes, vulnerable authentication workflows may match unintended entries or alter filter logic, which can undermine identity checks.
Is LDAP filter escaping the same as DN escaping?
No. Search filters and distinguished names use different escaping rules and should use context-specific encoders.
Does input validation replace LDAP escaping?
No. Validation is useful defense in depth, but values still need correct encoding for the LDAP context.
Is SQL parameterization applicable to LDAP?
Not directly. Use LDAP libraries/framework features and LDAP-specific escaping rather than SQL-oriented defenses.
Primary References
Protect Directory-Backed Authentication and APIs
Keep LDAP query structure fixed, encode values for the correct directory context and add runtime visibility around identity-facing APIs.
