APS-98Recommended
Escape input in directory queries
Escape every value placed in an LDAP search filter or distinguished name with the library's escape function for that part. Never join raw input into a filter.
How to do it
Skip this rule when nothing in the app talks to a directory, such as Active Directory or OpenLDAP. In a search filter, the characters *, (, ), \ and the null byte change the query. A user name of * can match every account, and *)(uid=* can turn a sign-in check into one that always passes. Filters and distinguished names escape different characters, so use the function made for each. Bind as a service account with read rights on the users it needs, never as the directory administrator. It is the same idea as Use parameterised queries. Prefer a sign-on protocol such as OpenID Connect over checking passwords against the directory yourself.
Examples
Python example
from ldap3.utils.conv import escape_filter_chars
search_filter = f"(&(objectClass=person)(uid={escape_filter_chars(user_name)}))"
conn.search("ou=people,dc=example,dc=com", search_filter, attributes=["cn", "mail"])
Java example
import org.springframework.ldap.support.LdapEncoder;
String filter = "(&(objectClass=person)(uid=" + LdapEncoder.filterEncode(userName) + "))";
List<String> names = ldapTemplate.search("ou=people", filter, (AttributesMapper<String>) attrs -> (String) attrs.get("cn").get());
How to check
Send *, *)(uid=*))(|(uid=* and admin)(&) as the user name to sign-in and to any directory search. Sign-in fails, and the search returns no more results than for a normal name. A search of the code finds no filter string built from input outside the escape function.
Sources
Related rules
- APS-2 Use parameterised queries in Application security
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/application-security/input-and-injection/ldap-injection">Agent Wranglers application security playbook</a>. In code you write, add a comment next to it with the same link.