-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathDataflowQueryTest.qll
More file actions
117 lines (94 loc) · 3.92 KB
/
DataflowQueryTest.qll
File metadata and controls
117 lines (94 loc) · 3.92 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
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
signature module QueryTestSig {
predicate isSink(DataFlow::Node sink);
predicate flowTo(DataFlow::Node sink);
}
module MakeQueryTest<QueryTestSig Impl> {
module DataFlowQueryTest implements TestSig {
string getARelevantTag() { result = "result" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node sink | Impl::flowTo(sink) |
location = sink.getLocation() and
tag = "result" and
value = "BAD" and
element = sink.toString()
)
}
// We allow annotating any sink with `result=OK` to signal
// safe sinks.
// Sometimes a line contains both an alert and a safe sink.
// In this situation, the annotation form `OK(safe sink)`
// can be useful.
predicate hasOptionalResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node sink | Impl::isSink(sink) |
location = sink.getLocation() and
tag = "result" and
value in ["OK", "OK(" + prettyNode(sink) + ")"] and
element = sink.toString()
)
}
}
import MakeTest<DataFlowQueryTest>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: result=BAD` or `result=OK` annotation" and
exists(DataFlow::Node sink |
exists(sink.getLocation().getFile().getRelativePath()) and
Impl::isSink(sink) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not Impl::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "result" and
missingResult.getValue() = "BAD" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
) and
not exists(GoodTestExpectation okResult |
okResult.getTag() = "result" and
okResult.getValue() in ["OK", "OK(" + prettyNode(sink) + ")"] and
okResult.getLocation().getFile() = location.getFile() and
okResult.getLocation().getStartLine() = location.getStartLine()
)
)
}
}
module FromDataFlowConfig<DataFlow::ConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) }
predicate flowTo(DataFlow::Node sink) { DataFlow::Global<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromDataFlowStateConfig<DataFlow::StateConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) or C::isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { DataFlow::GlobalWithState<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromTaintTrackingConfig<DataFlow::ConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) }
predicate flowTo(DataFlow::Node sink) { TaintTracking::Global<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromTaintTrackingStateConfig<DataFlow::StateConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) or C::isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { TaintTracking::GlobalWithState<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
deprecated signature class LegacyConfiguration extends DataFlow::Configuration;
deprecated module FromLegacyConfiguration<LegacyConfiguration C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { any(C c).isSink(sink) or any(C c).isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { any(C c).hasFlowTo(sink) }
}
import MakeQueryTest<Impl>
}