mirror of
https://github.com/github/codeql.git
synced 2025-12-20 02:44:30 +01:00
72 lines
2.3 KiB
Plaintext
72 lines
2.3 KiB
Plaintext
/**
|
|
* Provides classes for working with [LDAPjs](https://www.npmjs.com/package/ldapjs)
|
|
*/
|
|
|
|
import javascript
|
|
|
|
/**
|
|
* A module providing sinks and sanitizers for LDAP injection.
|
|
*/
|
|
module LdapJS {
|
|
/** Gets a reference to the ldapjs library. */
|
|
API::Node ldapjs() { result = API::moduleImport("ldapjs") }
|
|
|
|
/** Gets an LDAPjs client. */
|
|
private API::Node ldapClient() { result = ldapjs().getMember("createClient").getReturn() }
|
|
|
|
/** A call to a LDAPjs Client API method. */
|
|
class ClientCall extends API::CallNode {
|
|
string methodName;
|
|
|
|
ClientCall() {
|
|
methodName = ["add", "bind", "compare", "del", "modify", "modifyDN", "search"] and
|
|
this = ldapClient().getMember(methodName).getACall()
|
|
}
|
|
|
|
/** Gets the name of the LDAPjs Client API method. */
|
|
string getMethodName() { result = methodName }
|
|
}
|
|
|
|
/** A reference to a LDAPjs client `search` options. */
|
|
class SearchOptions extends API::Node {
|
|
SearchOptions() {
|
|
exists(ClientCall call | call.getMethodName() = "search" and this = call.getParameter(1))
|
|
}
|
|
}
|
|
|
|
/** A creation of an LDAPjs filter, or object containing a filter, that doesn't sanitizes the input. */
|
|
abstract class TaintPreservingLdapFilterStep extends DataFlow::Node {
|
|
/** Gets the input that creates (part of) an LDAPjs filter. */
|
|
abstract DataFlow::Node getInput();
|
|
|
|
/** Gets the resulting LDAPjs filter. */
|
|
abstract DataFlow::Node getOutput();
|
|
}
|
|
|
|
/** A call to the LDAPjs utility method "parseFilter". */
|
|
private class ParseFilter extends TaintPreservingLdapFilterStep, API::CallNode {
|
|
ParseFilter() { this = ldapjs().getMember("parseFilter").getACall() }
|
|
|
|
override DataFlow::Node getInput() { result = this.getArgument(0) }
|
|
|
|
override DataFlow::Node getOutput() { result = this }
|
|
}
|
|
|
|
/**
|
|
* A filter used in call to "search" on an LDAPjs client.
|
|
* We model that as a step from the ".filter" write to the options object itself.
|
|
*/
|
|
private class SearchFilter extends TaintPreservingLdapFilterStep {
|
|
SearchOptions options;
|
|
|
|
SearchFilter() {
|
|
options = ldapClient().getMember("search").getACall().getParameter(1) and
|
|
this = options.asSink()
|
|
}
|
|
|
|
override DataFlow::Node getInput() { result = options.getMember("filter").asSink() }
|
|
|
|
override DataFlow::Node getOutput() { result = this }
|
|
}
|
|
}
|