forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLDAPInjection.qll
More file actions
112 lines (99 loc) · 2.98 KB
/
LDAPInjection.qll
File metadata and controls
112 lines (99 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import go
/**
* A sanitizer function that prevents LDAP injection attacks.
*/
abstract class LdapSanitizer extends DataFlow::Node { }
/**
* A common sanitizer function. These are name-based heuristics only.
*/
private class CommonLdapEscape extends LdapSanitizer {
CommonLdapEscape() {
exists(DataFlow::MethodCallNode m |
m.getTarget().getName() in [
"sanitizedUserQuery", "sanitizedUserDN", "sanitizedGroupFilter", "sanitizedGroupDN"
]
|
this = m.getResult(0)
)
}
}
/**
* An `EscapeFilter` function from the `go-ldap` or `ldap` packages.
*/
private class EscapeFilterCall extends LdapSanitizer {
EscapeFilterCall() {
exists(Function f |
f.hasQualifiedName([
"github.com/go-ldap/ldap", "github.com/go-ldap/ldap/v3", "gopkg.in/ldap.v2",
"gopkg.in/ldap.v3"
], "EscapeFilter")
|
this = f.getACall()
)
}
}
/**
* A sink that is vulnerable to LDAP injection vulnerabilities.
*/
abstract class LdapSink extends DataFlow::Node { }
/**
* A vulnerable argument to `go-ldap` or `ldap`'s `NewSearchRequest` function.
*/
private class GoLdapSink extends LdapSink {
GoLdapSink() {
exists(Function f |
f.hasQualifiedName([
"github.com/go-ldap/ldap", "github.com/go-ldap/ldap/v3", "gopkg.in/ldap.v2",
"gopkg.in/ldap.v3"
], "NewSearchRequest")
|
this = f.getACall().getArgument([0, 6, 7])
)
}
}
/**
* A value written to the `ldap` package's `SearchRequest.BaseDN` field.
*/
private class LdapV2DNSink extends LdapSink {
LdapV2DNSink() {
exists(Field f, Write w |
f.hasQualifiedName(["gopkg.in/ldap.v2", "gopkg.in/ldap.v3"], "SearchRequest", "BaseDN") and
w.writesField(_, f, this)
)
}
}
/**
* An argument to `go-ldap-client`'s `LDAPClient.Authenticate` or `.GetGroupsOfUser` function.
*/
private class LdapClientSink extends LdapSink {
LdapClientSink() {
exists(Method m |
m.hasQualifiedName("github.com/jtblin/go-ldap-client", "LDAPClient",
["Authenticate", "GetGroupsOfUser"])
|
this = m.getACall().getArgument(0)
)
}
}
/**
* A value written to `go-ldap-client`'s `LDAPClient.Base` field.
*/
private class LdapClientDNSink extends LdapSink {
LdapClientDNSink() {
exists(Field f, Write w |
f.hasQualifiedName("github.com/jtblin/go-ldap-client", "LDAPClient", "Base") and
w.writesField(_, f, this)
)
}
}
private module LdapInjectionConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) { sink instanceof LdapSink }
predicate isBarrier(DataFlow::Node node) { node instanceof LdapSanitizer }
predicate observeDiffInformedIncrementalMode() { any() }
}
/**
* Tracks taint flow for reasoning about when a `ActiveThreatModelSource` flows
* into an argument or field that is vulnerable to LDAP injection.
*/
module LdapInjectionFlow = TaintTracking::Global<LdapInjectionConfig>;