Skip to content

Commit 99b273d

Browse files
Apply suggestions from code review
Added suggestion from atorralba. Co-authored-by: Tony Torralba <[email protected]>
1 parent e1b8fab commit 99b273d

File tree

1 file changed

+33
-59
lines changed

1 file changed

+33
-59
lines changed

java/ql/src/experimental/Security/CWE/CWE-470/LoadClassNoSignatureCheck.ql

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* potentially leading to arbitrary code execution.
77
* @problem.severity error
88
* @precision high
9+
* @kind problem
910
* @id java/unsafe-reflection
1011
* @tags security
1112
* experimental
@@ -16,55 +17,39 @@ import java
1617
import semmle.code.java.dataflow.DataFlow
1718
import semmle.code.java.dataflow.TaintTracking
1819

19-
ControlFlowNode getControlFlowNodeSuccessor(ControlFlowNode node)
20-
{
21-
result = node.getASuccessor()
22-
}
2320

2421
MethodAccess getClassLoaderReachableMethodAccess(DataFlow::Node node)
2522
{
26-
exists(
27-
MethodAccess maGetClassLoader, ControlFlowNode cfnGetClassLoader, ControlFlowNode cfnSuccessor |
23+
exists(MethodCall maGetClassLoader |
2824
maGetClassLoader.getCallee().getName() = "getClassLoader" and
2925
maGetClassLoader.getQualifier() = node.asExpr() and
30-
maGetClassLoader.getControlFlowNode() = cfnGetClassLoader and
31-
//cfnGetClassLoader.getASuccessor+() = cfnSuccessor and
32-
getControlFlowNodeSuccessor+(cfnGetClassLoader) = cfnSuccessor and
33-
cfnSuccessor instanceof MethodAccess and
34-
result = cfnSuccessor.(MethodAccess)
26+
result = maGetClassLoader.getControlFlowNode().getASuccessor+()
3527
)
3628
}
3729

3830
MethodAccess getDangerousReachableMethodAccess(MethodAccess ma)
3931
{
40-
(ma.getCallee().hasName("getMethod") or
41-
ma.getCallee().hasName("getDeclaredMethod")) and
42-
((
43-
exists(MethodAccess maInvoke |
44-
//ma.getControlFlowNode().getASuccessor*() = maInvoke and
45-
getControlFlowNodeSuccessor+(ma.getControlFlowNode()) = maInvoke and
46-
maInvoke.getCallee().hasName("invoke") and
47-
result = maInvoke
48-
)
49-
) or
50-
(
51-
exists(AssignExpr ae, VarAccess va1, VarAccess va2, MethodAccess maInvoke |
52-
ae.getSource() = ma and
53-
ae.getDest() = va1 and
54-
maInvoke.getQualifier() = va2 and
55-
va1.getVariable() = va2.getVariable() and
56-
result = maInvoke
57-
)
58-
))
32+
ma.getCallee().hasName(["getMethod", "getDeclaredMethod"]) and
33+
(
34+
result = ma.getControlFlowNode().getASuccessor*() and
35+
result.getCallee().hasName("invoke")
36+
or
37+
exists(AssignExpr ae |
38+
ae.getSource() = ma and
39+
ae.getDest().(VarAccess).getVariable() =
40+
result.getQualifier().(VarAccess).getVariable()
41+
)
42+
)
5943
}
6044

6145
module SignaturePackageConfig implements DataFlow::ConfigSig {
6246
predicate isSource(DataFlow::Node source) {
63-
exists(MethodAccess maCheckSignatures |
64-
maCheckSignatures.getCallee().getDeclaringType().getQualifiedName() = "android.content.pm.PackageManager" and
65-
maCheckSignatures.getCallee().getName() = "checkSignatures" and
66-
source.asExpr() = maCheckSignatures.getArgument(0)
67-
)
47+
exists(MethodCall maCheckSignatures |
48+
maCheckSignatures
49+
.getMethod()
50+
.hasQualifiedName("android.content.pm", "PackageManager", "checkSignatures") and
51+
source.asExpr() = maCheckSignatures.getArgument(0)
52+
)
6853
}
6954

7055
predicate isSink(DataFlow::Node sink) {
@@ -81,31 +66,20 @@ module SigPkgCfg = TaintTracking::Global<SignaturePackageConfig>;
8166

8267
predicate isSignaturesChecked(MethodAccess maCreatePackageContext)
8368
{
84-
exists(DataFlow::Node source, DataFlow::Node sink |
85-
SigPkgCfg::flow(source, sink) and
86-
sink.asExpr() = maCreatePackageContext.getArgument(0)
87-
)
69+
SigPkgCfg::flowToExpr(maCreatePackageContext.getArgument(0))
8870
}
8971

90-
from
91-
MethodAccess maCreatePackageContext,
92-
LocalVariableDeclExpr lvdePackageContext,
93-
DataFlow::Node sinkPackageContext,
94-
MethodAccess maGetMethod,
95-
MethodAccess maInvoke
72+
from
73+
MethodCall maCreatePackageContext, LocalVariableDeclExpr lvdePackageContext,
74+
Expr sinkPackageContext, MethodCall maGetMethod, MethodCall maInvoke
9675
where
97-
(maCreatePackageContext.getCallee().getDeclaringType().getQualifiedName() = "android.content.ContextWrapper" or
98-
maCreatePackageContext.getCallee().getDeclaringType().getQualifiedName() = "android.content.Context") and
99-
maCreatePackageContext.getCallee().getName() = "createPackageContext" and
100-
not isSignaturesChecked(maCreatePackageContext) and
101-
lvdePackageContext.getEnclosingStmt() = maCreatePackageContext.getEnclosingStmt() and
102-
TaintTracking::localTaint(DataFlow::exprNode(lvdePackageContext.getAnAccess()), sinkPackageContext) and
103-
getClassLoaderReachableMethodAccess(sinkPackageContext) = maGetMethod and
104-
getDangerousReachableMethodAccess(maGetMethod) = maInvoke
105-
select
106-
lvdePackageContext,
107-
sinkPackageContext,
108-
maGetMethod,
109-
maInvoke,
110-
"Potential arbitary code execution due to class loading without package signature checking."
76+
maCreatePackageContext
77+
.getMethod()
78+
.hasQualifiedName("android.content", ["ContextWrapper", "Context"], "createPackageContext") and
79+
not isSignaturesChecked(maCreatePackageContext) and
80+
lvdePackageContext.getEnclosingStmt() = maCreatePackageContext.getEnclosingStmt() and
81+
TaintTracking::localExprTaint(lvdePackageContext.getAnAccess(), sinkPackageContext) and
82+
getClassLoaderReachableMethodCall(sinkPackageContext) = maGetMethod and
83+
getGetMethodMethodCall(maGetMethod) = maInvoke
84+
select maInvoke, "Potential arbitary code execution due to $@ without $@ signature checking.", sinkPackageContext, "class loading", sinkPackageContext, "package"
11185

0 commit comments

Comments
 (0)