-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathConceptsTest.qll
More file actions
183 lines (163 loc) · 5.84 KB
/
ConceptsTest.qll
File metadata and controls
183 lines (163 loc) · 5.84 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
import python
import experimental.dataflow.DataFlow
import experimental.semmle.python.Concepts
import TestUtilities.InlineExpectationsTest
string value_from_expr(Expr e) {
// TODO: This one is starting to look like `repr` predicate from TestTaintLib
result =
e.(StrConst).getPrefix() + e.(StrConst).getText() +
e.(StrConst).getPrefix().regexpReplaceAll("[a-zA-Z]+", "")
or
result = e.(Name).getId()
or
not e instanceof StrConst and
not e instanceof Name and
result = e.toString()
}
class SystemCommandExecutionTest extends InlineExpectationsTest {
SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" }
override string getARelevantTag() { result = "getCommand" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SystemCommandExecution sce, DataFlow::Node command |
command = sce.getCommand() and
location = command.getLocation() and
element = command.toString() and
value = value_from_expr(command.asExpr()) and
tag = "getCommand"
)
}
}
class DecodingTest extends InlineExpectationsTest {
DecodingTest() { this = "DecodingTest" }
override string getARelevantTag() {
result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeMayExecuteInput"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Decoding d |
exists(DataFlow::Node data |
location = data.getLocation() and
element = data.toString() and
value = value_from_expr(data.asExpr()) and
(
data = d.getAnInput() and
tag = "decodeInput"
or
data = d.getOutput() and
tag = "decodeOutput"
)
)
or
exists(string format |
location = d.getLocation() and
element = format and
value = format and
format = d.getFormat() and
tag = "decodeFormat"
)
or
d.mayExecuteInput() and
location = d.getLocation() and
element = d.toString() and
value = "" and
tag = "decodeMayExecuteInput"
)
}
}
class CodeExecutionTest extends InlineExpectationsTest {
CodeExecutionTest() { this = "CodeExecutionTest" }
override string getARelevantTag() { result = "getCode" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(CodeExecution ce, DataFlow::Node code |
exists(location.getFile().getRelativePath()) and
code = ce.getCode() and
location = code.getLocation() and
element = code.toString() and
value = value_from_expr(code.asExpr()) and
tag = "getCode"
)
}
}
class SqlExecutionTest extends InlineExpectationsTest {
SqlExecutionTest() { this = "SqlExecutionTest" }
override string getARelevantTag() { result = "getSql" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(SqlExecution e, DataFlow::Node sql |
exists(location.getFile().getRelativePath()) and
sql = e.getSql() and
location = e.getLocation() and
element = sql.toString() and
value = value_from_expr(sql.asExpr()) and
tag = "getSql"
)
}
}
class HttpServerRouteSetupTest extends InlineExpectationsTest {
HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" }
override string getARelevantTag() { result in ["routeSetup", "routeHandler", "routedParameter"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(HTTP::Server::RouteSetup setup |
location = setup.getLocation() and
element = setup.toString() and
(
value = "\"" + setup.getUrlPattern() + "\""
or
not exists(setup.getUrlPattern()) and
value = ""
) and
tag = "routeSetup"
)
or
exists(HTTP::Server::RouteSetup setup, Function func |
func = setup.getARouteHandler() and
location = func.getLocation() and
element = func.toString() and
value = "" and
tag = "routeHandler"
)
or
exists(HTTP::Server::RouteSetup setup, Parameter param |
param = setup.getARoutedParameter() and
location = param.getLocation() and
element = param.toString() and
value = param.asName().getId() and
tag = "routedParameter"
)
}
}
class HttpServerHttpResponseTest extends InlineExpectationsTest {
File file;
HttpServerHttpResponseTest() { this = "HttpServerHttpResponseTest: " + file }
override string getARelevantTag() { result in ["HttpResponse", "responseBody", "mimetype"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
// By adding `file` as a class field, and these two restrictions, it's possible to
// say that we only want to check _some_ tags for certain files. This helped make
// flask tests more readable since adding full annotations for HttpResponses in the
// the tests for routing setup is both annoying and not very useful.
location.getFile() = file and
tag = getARelevantTag() and
(
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = "" and
tag = "HttpResponse"
)
or
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = value_from_expr(response.getBody().asExpr()) and
tag = "responseBody"
)
or
exists(HTTP::Server::HttpResponse response |
location = response.getLocation() and
element = response.toString() and
value = response.getMimetype() and
tag = "mimetype"
)
)
}
}