forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLoadClassNoSignatureCheck.ql
More file actions
94 lines (83 loc) · 3.1 KB
/
LoadClassNoSignatureCheck.ql
File metadata and controls
94 lines (83 loc) · 3.1 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
/**
* @name Load 3rd party classes or code ('unsafe reflection') without signature check
* @description Loading classes or code from third-party packages without checking the
* package signature could make the application
* susceptible to package namespace squatting attacks,
* potentially leading to arbitrary code execution.
* @problem.severity error
* @precision high
* @kind path-problem
* @id java/android/unsafe-reflection
* @tags security
* experimental
* external/cwe/cwe-470
*/
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.controlflow.Guards
import semmle.code.java.dataflow.SSA
import semmle.code.java.frameworks.android.Intent
class CheckSignaturesGuard extends Guard instanceof EqualityTest {
MethodCall checkSignatures;
CheckSignaturesGuard() {
this.getAnOperand() = checkSignatures and
checkSignatures
.getMethod()
.hasQualifiedName("android.content.pm", "PackageManager", "checkSignatures") and
exists(Expr signatureCheckResult |
this.getAnOperand() = signatureCheckResult and signatureCheckResult != checkSignatures
|
signatureCheckResult.(CompileTimeConstantExpr).getIntValue() = 0 or
signatureCheckResult
.(FieldRead)
.getField()
.hasQualifiedName("android.content.pm", "PackageManager", "SIGNATURE_MATCH")
)
}
Expr getCheckedExpr() { result = checkSignatures.getArgument(0) }
}
predicate signatureChecked(Expr safe) {
exists(CheckSignaturesGuard g, SsaDefinition v |
v.getARead() = g.getCheckedExpr() and
safe = v.getARead() and
g.controls(safe.getBasicBlock(), g.(EqualityTest).polarity())
)
}
module InsecureLoadingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) {
exists(Method m | m = src.asExpr().(MethodCall).getMethod() |
m.getDeclaringType().getASourceSupertype*() instanceof TypeContext and
m.hasName("createPackageContext") and
not signatureChecked(src.asExpr().(MethodCall).getArgument(0))
)
}
predicate isSink(DataFlow::Node sink) {
exists(MethodCall ma |
ma.getMethod().hasQualifiedName("java.lang", "ClassLoader", "loadClass")
|
sink.asExpr() = ma.getQualifier()
)
}
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(MethodCall ma, Method m |
ma.getMethod() = m and
m.getDeclaringType().getASourceSupertype*() instanceof TypeContext and
m.hasName("getClassLoader")
|
node1.asExpr() = ma.getQualifier() and
node2.asExpr() = ma
)
}
}
module InsecureLoadFlow = TaintTracking::Global<InsecureLoadingConfig>;
import InsecureLoadFlow::PathGraph
deprecated query predicate problems(
DataFlow::Node sinkNode, InsecureLoadFlow::PathNode source, InsecureLoadFlow::PathNode sink,
string message1, DataFlow::Node sourceNode, string message2
) {
InsecureLoadFlow::flowPath(source, sink) and
sinkNode = sink.getNode() and
message1 = "Class loaded from a $@ without signature check" and
sourceNode = source.getNode() and
message2 = "third party library"
}