Security Cipher

Security Resources

⌘K
  1. Home
  2. Security Resources
  3. Vulnerability Explain
  4. LDAP and XPath Injection

LDAP and XPath Injection

This Vulnerability Explain post covers LDAP Injection and its close relative XPath Injection. Both appear when applications build directory or XML queries from user input. They are less famous than SQL injection but just as capable of bypassing authentication and leaking data. Let’s see how they work.

What is LDAP Injection?

LDAP Injection happens when user input is inserted into an LDAP search filter without escaping, letting an attacker change the filter logic. XPath Injection is the same idea applied to XML documents queried with XPath.

Think of an LDAP login that searches for (&(uid=USERNAME)(password=PASS)). If the app drops your input straight in, sending a username like *)(uid=* or adding extra filter clauses can make the search always match, bypassing the password check.

How does LDAP Injection work?

LDAP and XPath injection follow the familiar untrusted-input-in-a-query pattern:

  • Input In a Filter
    • User input is concatenated into an LDAP filter or XPath query string.
  • Special Characters Unescaped
    • Characters like *, (, ), &, |, and ‘ are not escaped, so they alter the query structure.
  • Logic Manipulation
    • The attacker injects clauses or wildcards to change matching, for example forcing the filter to always be true.
  • Authentication Bypass or Disclosure
    • The manipulated query authenticates the attacker or returns records they should not see.
  • Blind Extraction
    • Where output is hidden, attackers infer data character by character using boolean responses.

Whether the backend is a directory service or an XML document, the lesson repeats: user input must never be allowed to rewrite the query that processes it.

LDAP injection diagram showing a wildcard and filter payload manipulating a directory search to bypass authentication

How LDAP injection works: special characters break out of the intended directory filter.

Tools and Techniques for LDAP Injection Testing

Testing relies on injecting filter metacharacters and observing changes in matching.

Manual Testing Methodologies

  • Filter Breakout – Inject characters like *, ), and ( into login and search fields and watch for changed results.
  • Always-True Clauses – Add clauses such as )(uid=*) to force the filter to match everything.
  • Boolean Blind Testing – Use true/false conditions to infer data when results are not directly shown.
  • XPath Probing – For XML backends, inject ‘ or ‘1’=’1 style payloads into XPath expressions.

Automated Scanning Tools

  • sqlmap – Supports some XPath/LDAP-style testing alongside SQL injection.
  • Burp Suite Scanner – Detects LDAP and XPath injection.
  • OWASP ZAP – Free scanner with injection detection rules.
  • Nuclei – Templates cover common injection signatures.

LDAP Injection Protection Mechanisms

Best Practices for Secure Coding

  • Escape Filter Special Characters
    • Description: Escape LDAP and XPath metacharacters in all user input.
    • Benefits: Input can no longer alter the query structure.
    • Implementation Tip: Use built-in escaping APIs rather than hand-rolled replacements.
  • Use Parameterized Queries
    • Description: Use APIs that separate the query from the data where available.
    • Benefits: Treats input strictly as values.
    • Implementation Tip: For XPath, use variable binding instead of string concatenation.
  • Validate Input Strictly
    • Description: Allowlist acceptable characters for fields like usernames.
    • Benefits: Rejects payloads before they reach the query.
    • Implementation Tip: Disallow filter metacharacters in identifiers.

Best Practices for Organizations

  • Least Privilege Binds
    • Use a low-privilege service account for directory searches.
    • Avoid binding with administrative credentials.
  • Centralized Auth
    • Prefer a vetted authentication library over hand-built LDAP logins.
    • Reuse a single hardened directory access layer.
  • Testing
    • Add LDAP and XPath injection checks to security testing.
    • Review every directory or XML query that uses input.

Top LDAP Injection payloads used by Security Researchers

As a security researcher, knowing the most common payloads helps you detect and prevent these attacks. Use this knowledge ethically and only on systems you are authorized to test. Some sample payloads are shown below.

// LDAP authentication bypass
username: *)(uid=*))(|(uid=*
password: anything
// LDAP always-true wildcard
username: admin)(&)
username: *
// XPath authentication bypass
' or '1'='1
' or 1=1 or 'a'='a
// Blind XPath boolean extraction
' and string-length(//user[1]/password)=8 and '1'='1

Real-World Example: Directory Login Bypass

An intranet portal authenticated staff against LDAP using the filter (&(uid=)(userPassword=)) built by string concatenation.

A tester supplied the username *)(uid=*))(|(uid=* which restructured the filter so it always matched a valid user, logging them in without a correct password.

The fix escaped all filter input and validated usernames against an allowlist. LDAP and XPath injection round out the injection family with the same moral: escape and parameterize, always.

Vulnerable and secure code of LDAP Injection

The following example shows the contrast between vulnerable and secure code for LDAP Injection. It helps you see how the flaw creeps into real code and the changes that shut it down.

🥺 Vulnerable Code:

// Vulnerable: user input concatenated into an LDAP filter
String user = request.getParameter("user");
String pass = request.getParameter("pass");
String filter = "(&(uid=" + user + ")(userPassword=" + pass + "))";
NamingEnumeration<SearchResult> results =
    ctx.search("ou=people,dc=example,dc=com", filter, controls);
  • Metacharacters like ) and * in the input rewrite the filter logic.
  • An attacker can force the filter to match any user and bypass the password.

😎 Secure Code:

// Secure: escape input and validate the identifier
import org.springframework.ldap.support.LdapEncoder;

String user = request.getParameter("user");
String pass = request.getParameter("pass");
if (!user.matches("[a-zA-Z0-9._-]+")) {
    throw new IllegalArgumentException("Invalid username");
}
String filter = "(&(uid=" + LdapEncoder.filterEncode(user) +
                ")(userPassword=" + LdapEncoder.filterEncode(pass) + "))";
  • filterEncode escapes LDAP metacharacters so input cannot change the filter.
  • An allowlist on the username rejects payloads outright.

Conclusion

LDAP and XPath injection are the quieter members of the injection family, but they bypass logins and leak data just as effectively. Escape all filter metacharacters, use parameterized or variable-bound queries, validate identifiers against an allowlist, and bind with least-privilege accounts. The backend changes; the discipline of separating data from query does not.

How can we help?