This article explains LDAP injection, a directory service attack analogous to SQL injection, where an attacker manipulates LDAP search filters by injecting unescaped special characters into login forms. The DirectoryBox lab demonstrates how concatenating user input directly into LDAP filters allows attackers to rewrite query logic and bypass authentication. Understanding this vulnerability matters because it exposes how directory-based authentication systems in enterprise environments can be compromised when input validation is neglected.
- LDAP filters as query languageLDAP search filters use their own syntax with metacharacters such as parentheses, wildcards, and AND/OR operators. When user input is concatenated directly into a filter without escaping, these metacharacters are interpreted as part of the query structure rather than literal text, allowing attackers to change what the filter actually asks for.
- Login bypass mechanismDirectoryBox builds a filter meaning 'find the entry where username matches AND password matches' by concatenating both values. An attacker can inject LDAP syntax in the username field (such as characters that close the password condition) followed by an always-true condition, transforming the filter to 'username is admin AND (anything)' to match the admin entry without knowing the real password.
- Attack execution on DirectoryBoxThe attacker supplies the admin username followed by LDAP filter syntax that removes the password requirement, then uses a wildcard or always-true condition in place of the password. When submitted, the manipulated filter resolves as a match, granting admin access regardless of what password was actually entered.
- RFC 4515 escaping requirementDefense requires escaping specific characters—parentheses, asterisks, backslashes, forward slashes, and NUL—according to RFC 4515 rules before any user value enters an LDAP filter. Failure to apply these escape rules leaves the application vulnerable to injection.
- Parameterised API as safer alternativeUsing a parameterised directory API keeps user data out of filter syntax entirely, preventing metacharacters from being interpreted as query logic. This approach is preferred over manual escaping because it separates data from structure by design.
- Binding over password filteringAuthenticating by binding directly to the directory with the user's credentials is safer than string-matching passwords inside filters because it avoids placing the password in the filter string altogether. This shifts authentication responsibility to the directory service itself rather than the application's filter construction.
- Detection and reconnaissanceA simple reconnaissance technique involves entering a stray parenthesis or asterisk in the username field during login. If this causes the error or result to change, the input is reaching an unescaped LDAP filter, indicating the application is vulnerable.
- Prevalence in enterprise environmentsLDAP injection appears in enterprise applications that authenticate against Active Directory or other directory services by building filters from form input. While less common than SQL injection due to fewer apps using LDAP directly, it is classified under Injection (A03) in the OWASP Top 10 (2021).
Bottom line: LDAP injection stems from the same root cause as SQL injection—concatenating untrusted user input into a query language—and must be prevented by escaping input per RFC 4515, using parameterised directory APIs, or authenticating via directory binding instead of password filtering. Testing user input with special characters is a quick way to detect whether an application's login is vulnerable to this attack.
📋 In this walkthrough
What this lab teaches
LDAP injection is the same family as SQL injection, aimed at a directory service. When an app concatenates user input into an LDAP search filter, special filter characters let an attacker change the query's logic — for example turning a password check into a condition that is always true.
The lesson: directory filters are a query language too. Untrusted input must be escaped before it goes anywhere near the filter string.
How DirectoryBox checks your login
DirectoryBox builds a filter that means 'find the entry where the username matches and the password matches', concatenating both values in directly. Because your input lands inside the filter unescaped, filter metacharacters you send are interpreted as part of the query, not as literal text.
The attack approach
- Notice the login builds an LDAP filter from your username and password.
- Use LDAP filter syntax in the input so the password condition no longer has to be true.
- Make the filter match the admin entry regardless of the password supplied.
- Submit and land in the admin session.
Full walkthrough (spoiler)
If the filter still rejects you, the syntax is not closing the way you expect — open the steps.
Show the step-by-step solution
- In the username field, supply the admin account followed by LDAP filter syntax that makes the overall filter match on the username alone.
- Use a wildcard or an always-true condition in place of the password so that half of the filter is satisfied by anything.
- Submit. The filter now resolves to 'username is admin AND (anything)', so the admin entry matches without the real password.
- You are logged in as admin and the lab marks you solved.
Why it works
The server trusts your input to be plain text, but it is pasted into a structured filter. LDAP metacharacters such as parentheses, wildcards and the AND/OR operators then change the shape of the query. The password check is no longer a check — it is a condition you control.
Where this happens in the real world
LDAP injection shows up in enterprise apps that authenticate against Active Directory or another directory service by building filters from form input. It is less common than SQL injection only because fewer apps talk LDAP directly, and it sits under Injection (A03) in the OWASP Top 10 (2021).
How to defend against it
- Escape every user value that enters a filter using the RFC 4515 rules (the characters
()*\\/and NUL). - Prefer a parameterised directory API that keeps data out of the filter syntax.
- Bind with the user's credentials rather than string-matching a password inside a filter.
- Validate input against an allowlist of expected characters where you can.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
