-
Notifications
You must be signed in to change notification settings - Fork 1
/
query_3.ql
147 lines (125 loc) · 4.73 KB
/
query_3.ql
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
147
/**
* @kind path-problem
*/
import java
import semmle.code.java.dataflow.TaintTracking
import DataFlow::PathGraph
class ConstraintValidator extends RefType {
ConstraintValidator() {
this.hasQualifiedName("javax.validation", "ConstraintValidator")
}
}
predicate overridesAConstraintValidatorMethod(Method override) {
exists(Method base |
base.getSourceDeclaration().getDeclaringType() instanceof ConstraintValidator and
override.overrides(base)
)
}
class ConstraintValidatorSource extends Method {
ConstraintValidatorSource() {
this.getName() = "isValid" and
overridesAConstraintValidatorMethod(this)
}
}
class ConstraintValidatorContext extends RefType {
ConstraintValidatorContext() {
this.hasQualifiedName("javax.validation", "ConstraintValidatorContext")
}
}
class ConstraintValidatorContextSink extends MethodAccess {
ConstraintValidatorContextSink() {
this.getCallee().getName() = "buildConstraintViolationWithTemplate" and
this.getCallee().getDeclaringType() instanceof ConstraintValidatorContext
}
}
class ELInjectionInCustomConstraintValidatorsConfig extends TaintTracking::Configuration {
ELInjectionInCustomConstraintValidatorsConfig() { this = "ELInjectionInCustomConstraintValidatorsConfig" }
override predicate isSource(DataFlow::Node source) {
exists(ConstraintValidatorSource isValid |
source.asParameter() = isValid.getParameter(0)
)
}
override predicate isSink(DataFlow::Node sink) {
exists(ConstraintValidatorContextSink buildWithTemplate |
sink.asExpr() = buildWithTemplate.getArgument(0)
)
}
}
class GetConstraints extends Method {
GetConstraints() {
(
this.getName() = "getHardConstraints" or
this.getName() = "getSoftConstraints"
) and
this.getDeclaringType().hasQualifiedName("com.netflix.titus.api.jobmanager.model.job", "Container")
}
}
class GetConstraintsCall extends MethodAccess {
GetConstraintsCall() {
this.getCallee() instanceof GetConstraints
}
}
predicate hashSetConstructorStep(DataFlow::Node step1, DataFlow::Node step2) {
exists(ConstructorCall call |
call.getConstructedType().getQualifiedName().matches("java.util.HashSet<%>") and
step1.asExpr() = call.getArgument(0) and
step2.asExpr() = call
)
}
class HashSetConstructorTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node step1, DataFlow::Node step2) {
hashSetConstructorStep(step1, step2)
}
}
class ChainableMethod extends Method {
ChainableMethod() {
this instanceof GetConstraints or
this.getName().regexpMatch("keySet|stream|map|collect")
}
}
predicate chainedCallsOnSourceStep(DataFlow::Node step1, DataFlow::Node step2) {
exists(ConstraintValidatorSource origin, MethodAccess chainedCall |
chainedCall.getQualifier*() = origin.getParameter(0).getAnAccess() and
chainedCall.getMethod() instanceof ChainableMethod and
step1.asExpr() = chainedCall.getQualifier() and
step2.asExpr() = chainedCall
)
}
class ChainedCallsOnSourceTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node step1, DataFlow::Node step2) {
chainedCallsOnSourceStep(step1, step2)
}
}
class HeuristicGetMessageCall extends MethodAccess {
HeuristicGetMessageCall() {
this.getMethod().getName().matches("get%Message")
}
}
class ThrowingCall extends MethodAccess {
CatchClause catch;
ThrowingCall() {
exists(Exception exception |
this.getEnclosingStmt().getEnclosingStmt*() = catch.getTry().getBlock() and
this.getMethod().getSourceDeclaration().getAnException() = exception and
exception.getType().getAnAncestor() = catch.getACaughtType()
)
}
CatchClause getCatch() {
result = catch
}
}
predicate throwingCallToGetMessageStep(DataFlow::Node step1, DataFlow::Node step2) {
exists(ThrowingCall throwingCall, HeuristicGetMessageCall getMessageCall |
throwingCall.getCatch().getVariable().getAnAccess() = getMessageCall.getQualifier() and
step1.asExpr() = throwingCall.getArgument(0) and
step2.asExpr() = getMessageCall
)
}
class ThrowingCallTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node step1, DataFlow::Node step2) {
throwingCallToGetMessageStep(step1, step2)
}
}
from ELInjectionInCustomConstraintValidatorsConfig cfg, DataFlow::PathNode source, DataFlow::PathNode sink
where cfg.hasFlowPath(source, sink)
select sink, source, sink, "Custom constraint error message contains unsanitized user data"