LDAP Injection

Lecture

What is LDAP?

Lightweight Directory Access Protocol (LDAP) is a common software protocol designed to enable anyone on a network to find resources such as other individuals, files, and devices. Directory services such as LDAP are useful for intranets. It can also be used to store usernames and passwords as part of a single sign-on (SSO) system.

What is LDAP Injection?

LDAP injection is a vulnerability in which queries are constructed from untrusted input without prior validation or sanitization.

LDAP uses queries constructed from predicates that involve the use of special characters (e.g., brackets, asterisks, ampersands, or quotes). Metacharacters such as these control the meaning of the query; thereby, affecting the type and number of objects retrieved from the underlying directory. If an attacker can submit input containing these control characters, they can alter the query and change the intended behavior.

Attack

The application architecture that supports LDAP includes both server-side and client-side components. The LDAP queries submitted to the server are known as LDAP search filters, which are constructed using prefix notation. For example, 1 + 2 is + 1 2 in prefix notation. Below is an example of an LDAP search filter:

find("(&(cn=" + username +")(userPassword=" + pass +"))")

This search filter means find an LDAP node with the condition (cn=" + username +") & (userPassword=" + pass +") == True. This prefix filter notation instructs the query to find an LDAP node with the given username and password. Consider a scenario where this query is constructed by appending the username and password strings obtained from an HTML form. If these user-controlled values are appended to the LDAP search filter without any validation or sanitization, a username and password value of * changes the intended meaning of the query and returns a list of all users. Special characters other than * can also create malicious queries. If the username value is set to *)(cn=*))(|(cn=*, the effective search filter becomes:

find("(&(cn=*)(cn=*))(|(cn=*)(userPassword=" + pass +"))")

The highlighted condition in the above query always evaluates to true. If this query is used within an authentication flow, an attacker can easily bypass authentication controls with the above payload.

Here is a list of potential payloads that you can try:

Defense

LDAP injection attacks primarily occur due to missing or weak input validation.

Validation consists of rejecting malformed input or stripping malicious LDAP control characters before including untrusted input within a query. Below are several actionable methods you can leverage:

  • Enforce input validation

    • Prior to including untrusted input in LDAP queries, the input should be validated against a prefer list of allowed strings or characters. This validation should always be conducted server-side even if the input is previously validated client-side.

    • Structured inputs like social security numbers, phone numbers, and email addresses can be validated using a strong regular expression pattern. Inputs like usernames should be validated against an approved set of characters that exclude LDAP filter control characters.

  • Escape input with encoding

    • Escape user-controlled input strings in such a way that any control characters in the input don’t change the intended meaning of the LDAP search filter. For example, in a Java application, metacharacters in an LDAP query can be prepared with backslashes as escape characters. With this method, untrusted inputs are appended to a search filter are as literal string values, not as LDAP predicates.

  • Harden directory authorization

    • This defense technique is meant to minimize the impact of any injection attempt by employing the principle of least privilege. The LDAP account used for binding the directory in an application must have restricted access. With this approach, only authorized LDAP queries can be executed against the LDAP server.

Reference

Last updated