-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathResearchMode.qll
118 lines (112 loc) · 4.02 KB
/
ResearchMode.qll
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 java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSteps
import semmle.code.java.dataflow.ExternalFlow
/**
* Taintsteps to enable this -> read flow
* eg: this.field
*/
class FieldReadTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(FieldRead fa |
n1 = DataFlow::getFieldQualifier(fa) and
n2.asExpr() = fa
)
}
}
/**
* Treats a field write as a jump step (one that discards calling context, and supposes that probably at some point a read step takes place)
*/
class FieldTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
// From field write to read
exists(Field f, RefType t |
n1.asExpr() = f.getAnAssignedValue() and
n2.asExpr() = f.getAnAccess() and
n1.asExpr().getEnclosingCallable().getDeclaringType() = t and
n2.asExpr().getEnclosingCallable().getDeclaringType() = t
)
}
}
/**
* Create jump steps for methods connected by the wait/notify pattern
*/
class NotifyWaitTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(
MethodCall notify, RefType t, MethodCall wait, SynchronizedStmt notifySync,
SynchronizedStmt waitSync
|
notify.getMethod().getName() = ["notify", "notifyAll"] and
notify.getAnEnclosingStmt() = notifySync and
notifySync.getExpr().getType() = t and
wait.getMethod().getName() = "wait" and
wait.getAnEnclosingStmt() = waitSync and
waitSync.getExpr().getType() = t and
exists(AssignExpr write, FieldAccess read, Field f |
write.getAnEnclosingStmt() = notifySync and
write.getDest().(FieldAccess).getField() = f and
write = n1.asExpr() and
read.getAnEnclosingStmt() = waitSync and
read.getField() = f and
read = n2.asExpr()
)
)
}
}
/**
* Convey taint from the argument of a method call that can throw an exception
* to the exception variable in the correspondinf catch block
*/
class ExceptionTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(Call call, TryStmt t, CatchClause c, MethodCall gm |
call.getEnclosingStmt().getEnclosingStmt*() = t.getBlock() and
t.getACatchClause() = c and
(
call.getCallee().getAThrownExceptionType().getASubtype*() = c.getACaughtType() or
c.getACaughtType().getASupertype*() instanceof TypeRuntimeException
) and
c.getVariable().getAnAccess() = gm.getQualifier() and
gm.getMethod().getName().regexpMatch("get(Localized)?Message|toString") and
n1.asExpr() = call.getAnArgument() and
n2.asExpr() = gm
)
}
}
/**
* Convey taint from globally tainted objects to their fields
*/
private class GetterTaintStep extends TaintTracking::AdditionalTaintStep {
override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
exists(MethodCall ma, Method m |
ma.getMethod() = m and
m.getName().matches("get%") and
m.getNumberOfParameters() = 0 and
n1.asExpr() = ma.getQualifier() and
n2.asExpr() = ma
)
}
}
/*
* private class SetterTaintStep extends TaintTracking::AdditionalTaintStep {
* override predicate step(DataFlow::Node n1, DataFlow::Node n2) {
* exists(MethodCall ma, Method m |
* ma.getMethod() = m and
* m.getName().matches("set%") and
* m.getNumberOfParameters() = 1 and
* ma.getEnclosingCallable().getDeclaringType().getName().matches("%Factory") and
* n1.asExpr() = ma.getArgument(0) and
* n2.asExpr() = ma.getQualifier()
* )
* }
* }
*
* class GlobalSanitizer extends TaintTracking::Sanitizer {
* override predicate sanitize(DataFlow::Node node) {
* node.asExpr().(MethodCall).getMethod().hasName("getInputStream") or
* node.asExpr().(MethodCall).getMethod().hasName("getHostName")
* }
* }
*/