Why LDAP Filter Escaping Matters
LDAP filter escaping is a fundamental, security-critical step in constructing LDAP search filters. In practice, anywhere user input or dynamic data is interpolated into LDAP filters, escaping ensures the filter remains correct and safe. Escaping the wrong way—or neglecting it entirely—leads directly to authentication failures, search mismatches, or far worse: vulnerabilities such as LDAP injection.
An LDAP filter matches directory entries based on rules like (cn=John Smith). If the assertion value contains special characters, their unescaped presence might terminate the value early, alter filter logic, or even enable a user to manipulate the query. Therefore, precise escaping, per spec, is required to make filters both syntactically valid and secure.
LDAP Filter Escaping Rules: The RFC 4515 Standard
LDAP filter assertion value escaping is defined by RFC 4515. Only five specific characters in assertion values require escaping:
| Character | Description | Escape Sequence |
|---|---|---|
| * | Wildcard | \2a |
| ( | Left parenthesis | \28 |
| ) | Right parenthesis | \29 |
| \ | Backslash | \5c |
| NUL | Null byte (U+0000) | \00 |
Escaping is required because these characters play special syntactic roles in filter expressions:
*is the wildcard character in substring filters.(and)delimit filter expressions.\is the escape indicator itself.- NUL is illegal and signals the end of a value in C-based directories.
No other characters—such as commas, plus signs, equals, or non-ASCII Unicode—require escaping in filter assertion values, even though they may be special elsewhere in LDAP (notably in distinguished names, or DNs).
Example
Suppose your input is an asterisk:
- Raw:
(cn=*) - Escaped (find entry with literal asterisk in CN):
(cn=\2a)
How to Escape: Syntax and Practical Examples
In filters, escaped characters are represented as a backslash followed by their two-digit hexadecimal code (case-insensitive). The conversion occurs only within assertion values, not in attribute names or filter operators.
Escaping Table
| Input | Escaped Representation |
|---|---|
abc*def | (cn=abc\2adef) |
(a)b(c) | (description=\28a\29b\28c\29) |
foo\bar | (cn=foo\5cbar) |
before\0after | (attribute=before\00after) |
Key Points
- The hex sequence uses two lowercase or uppercase digits.
- The backslash (
\) introduces an escape. For example,\2ais an asterisk. - Escaped hex is always interpreted as a literal character in the value.
- Only filter assertion values—not operators or attribute names—use this escaping.
Always use a library function for escaping, not manual substitution, to avoid missing edge cases.
Distinguished Name vs. Filter Escaping: Know the Difference
A common and dangerous error is to apply filter escaping rules to distinguished names (DNs), or vice versa. Each context is governed by a different RFC:
- Filter assertion values (RFC 4515): Only
*,(,),\, and NUL must be escaped (\2a,\28,\29,\5c,\00). - Distinguished Names (RFC 4514): Requires escaping commas, plus, quotes, equal signs, less-than/greater-than, semicolons, number sign, and leading/trailing spaces, using a different escape mechanism.
| Character | Filter Assertion Value (RFC 4515) | DN Value (RFC 4514) |
|---|---|---|
* | Escaped (\2a) | No (unless at start/end) |
, (comma) | No | Escaped (\,) |
= | No | Escaped (\=) |
(, ) | Escaped (\28, \29) | No |
\ | Escaped (\5c) | Escaped (\\) |
| NUL | Escaped (\00) | Escaped (\00) |
| Space (edge pos.) | No | Escaped (\ ) |
Applying the wrong rules yields invalid filters or search mismatches. Never conflate DN and filter value escaping.
Security Implications: Preventing LDAP Injection
LDAP injection is a serious risk whenever user input is interpolated into search filters without escaping. An attacker could supply a value like *)(|(cn=*)), which, unescaped, turns a intended 1:1 lookup into a match-all filter—a classic injection attack.
Proper escaping ensures that every character in user input becomes a harmless literal, never a filter operator or delimiter. Code must always use an escaping routine that fully implements RFC 4515; manual string concatenation or ad-hoc "sanitizers" are a major vulnerability. Escaping must never be omitted, even if input "looks safe".
Platform Differences: AD vs. OpenLDAP
Both OpenLDAP and Microsoft Active Directory adhere to RFC 4515 for LDAP filter assertion value escaping. No additional or deviating filter-side escaping requirements are imposed by either, and the five-character rule applies directly.
However, platform-specific tools or libraries for manipulating distinguished names may use stricter—or simply different—escaping (see RFC 4514, especially for DNs in Microsoft ecosystems). It is crucial to always distinguish the filter assertion escaping context (where the rules are uniform) from the DN context (where they are not).
Common Mistakes and Misconceptions
Myth: "All special characters need escaping in filters."
Reality: Only*,(,),\, and NUL need escaping in filter assertion values.Myth: "Comma or equal signs require escaping in filters as they do in DNs."
Reality: They do not. DN escaping rules are broader and not interchangeable with filter value rules.Myth: "Libraries always over-escape or under-escape—manual escaping is safer."
Reality: Manual escaping is highly error-prone. Use a standards-based, well-maintained routine.Myth: "Non-ASCII characters must be escaped in filters."
Reality: Only the five characters require escaping, regardless of Unicode content.Myth: "Filter assertion values, attribute names, and control characters use the same escaping."
Reality: Only assertion values are escaped; attribute names never are.
Summary Table: LDAP Filter Escaping Cheat Sheet
| Character | Must Escape in Filter? | Escape Sequence |
|---|---|---|
| * | Yes | \2a |
| ( | Yes | \28 |
| ) | Yes | \29 |
| \ | Yes | \5c |
| NUL | Yes | \00 |
| , = + < > # | No | — |
| Non-ASCII | No (unless above) | — |
Refer to this table whenever in doubt about which characters require escaping in LDAP filters.
Further Reading and Authoritative References
- RFC 4515: Lightweight Directory Access Protocol (LDAP)—The authoritative source for filter escaping rules, including full syntax and rationale.
- RFC 2254: The String Representation of LDAP Search Filters—Historical standard, now replaced by RFC 4515.
- Search Filter Syntax (Microsoft)—Covers Microsoft Active Directory filter syntax and clarifies escaping requirements.
- about_ActiveDirectory_Filter (PowerShell)—Microsoft command-line reference for filter usage and syntax.
- OpenLDAP Administrator’s Guide—Official documentation for filter construction, referencing RFC 4515.
- RFC 4514—The contrasting standard for distinguished name escaping, not for filter values.
Correct LDAP filter escaping is a precise task, governed by RFC 4515. Misapplying or neglecting these rules is a leading cause of both interoperability bugs and critical security issues. Always use a reliable library routine, escape only the five required characters in filter values, and never reuse DN escaping logic for filters—or vice versa.