forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLDAPInjectionQuery.qll
More file actions
146 lines (130 loc) · 4.75 KB
/
LDAPInjectionQuery.qll
File metadata and controls
146 lines (130 loc) · 4.75 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/**
* Provides a taint-tracking configuration for reasoning about unvalidated user input that is used to
* construct LDAP queries.
*/
import csharp
private import semmle.code.csharp.security.dataflow.flowsinks.FlowSinks
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
private import semmle.code.csharp.frameworks.system.DirectoryServices
private import semmle.code.csharp.frameworks.system.directoryservices.Protocols
private import semmle.code.csharp.security.Sanitizers
private import semmle.code.csharp.dataflow.internal.ExternalFlow
/**
* A data flow source for unvalidated user input that is used to construct LDAP queries.
*/
abstract class Source extends DataFlow::Node { }
/**
* A data flow sink for unvalidated user input that is used to construct LDAP queries.
*/
abstract class Sink extends ApiSinkExprNode { }
/**
* A sanitizer for unvalidated user input that is used to construct LDAP queries.
*/
abstract class Sanitizer extends DataFlow::ExprNode { }
/**
* A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
*/
module LdapInjectionConfig implements DataFlow::ConfigSig {
/**
* Holds if `source` is a relevant data flow source.
*/
predicate isSource(DataFlow::Node source) { source instanceof Source }
/**
* Holds if `sink` is a relevant data flow sink.
*/
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
/**
* Holds if data flow through `node` is prohibited. This completely removes
* `node` from the data flow graph.
*/
predicate isBarrier(DataFlow::Node node) { node instanceof Sanitizer }
}
/**
* A taint-tracking configuration for unvalidated user input that is used to construct LDAP queries.
*/
module LdapInjection = TaintTracking::Global<LdapInjectionConfig>;
/** A source supported by the current threat model. */
class ThreatModelSource extends Source instanceof ActiveThreatModelSource { }
/** LDAP sinks defined through Models as Data. */
private class ExternalLdapExprSink extends Sink {
ExternalLdapExprSink() { sinkNode(this, "ldap-injection") }
}
/**
* An argument that sets the `Path` property of a `DirectoryEntry` object that is a sink for LDAP
* injection.
*
* This is either an argument to the constructor, or to the setter for the property.
*/
class DirectoryEntryPathSink extends Sink {
DirectoryEntryPathSink() {
exists(ObjectCreation create |
create.getTarget() = any(SystemDirectoryServicesDirectoryEntryClass d).getAConstructor()
|
this.getExpr() = create.getArgumentForName("path")
)
or
exists(Property path |
path = any(SystemDirectoryServicesDirectoryEntryClass d).getAProperty() and
path.hasName("Path")
|
this.getExpr() = path.getSetter().getACall().getArgument(0)
)
}
}
/**
* A argument that sets the `Filter` property of a `DirectorySearcher` object that is a sink for
* LDAP injection.
*
* This is either an argument to the constructor, or to the setter for the property.
*/
class DirectorySearcherFilterSink extends Sink {
DirectorySearcherFilterSink() {
exists(ObjectCreation create |
create.getTarget() = any(SystemDirectoryServicesDirectorySearcherClass d).getAConstructor()
|
this.getExpr() = create.getArgumentForName("filter")
)
or
exists(Property filter |
filter = any(SystemDirectoryServicesDirectorySearcherClass d).getAProperty() and
filter.hasName("Filter")
|
this.getExpr() = filter.getSetter().getACall().getArgument(0)
)
}
}
/**
* A argument that sets the `Filter` property of a `SearchRequest` object that is a sink for
* LDAP injection.
*
* This is either an argument to the constructor, or to the setter for the property.
*/
class SearchRequestFilterSink extends Sink {
SearchRequestFilterSink() {
exists(ObjectCreation create |
create.getTarget() = any(SystemDirectoryServicesProtocolsSearchRequest d).getAConstructor()
|
this.getExpr() = create.getArgumentForName("ldapFilter") or
this.getExpr() = create.getArgumentForName("filter")
)
or
exists(Property filter |
filter = any(SystemDirectoryServicesProtocolsSearchRequest d).getAProperty() and
filter.hasName("Filter")
|
this.getExpr() = filter.getSetter().getACall().getArgument(0)
)
}
}
/**
* A call to a method which is named "LDAP*Encode", which is likely to be an LDAP sanitizer.
*
* This will match the encoding methods provided by the AntiXSS library.
*/
class LdapEncodeSanitizer extends Sanitizer {
LdapEncodeSanitizer() {
this.getExpr().(MethodCall).getTarget().getName().regexpMatch("(?i)LDAP.*Encode.*")
}
}
private class SimpleTypeSanitizer extends Sanitizer, SimpleTypeSanitizedExpr { }
private class GuidSanitizer extends Sanitizer, GuidSanitizedExpr { }