RSTR-LDAP-001 — ldapjs search with template-literal filter
Summary
An LDAP search call is given a filter built by string
interpolation: `(uid=${userInput})`. The LDAP filter
grammar has metacharacters (*, (, ), \, NUL) that
let an attacker rewrite the filter:
*)(uid=*matches everything;*)(|(role=admin)enumerates admins;*)(uid=*))(|(&(uid=*opens the door to filter-tree injection.
This is the LDAP cousin of SQL injection.
Severity
High.
Languages
JavaScript / TypeScript.
How to fix it
Escape every interpolated value with the LDAP filter character escape:
import ldapEscape from 'ldap-escape';
client.search('dc=example,dc=com', {
filter: `(uid=${ldapEscape.filter`${userInput}`})`,
});
Or build the filter from a structured object via
ldapjs.parseFilter so there's no string to interpolate
into at all.