Skip to content

Commit fd66f47

Browse files
committed
Added LoadClassNoSignatureCheck.ql
1 parent 01a074c commit fd66f47

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
2+
<qhelp>
3+
4+
<overview>
5+
<p>
6+
If a vulnerable app obtains the ClassLoader of any app based solely on the package name without checking the package signature
7+
allow attacker to create application with the targeted package name for "package namespace squatting".
8+
If the victim install such malicious app in the same device as the vulnerable app, the vulnerable app would load
9+
classes or code from the malicious app, potentially leading to arbitrary code execution.
10+
</p>
11+
</overview>
12+
13+
<recommendation>
14+
<p>
15+
Verify that the signature of an app in addition to the package name before loading the classes or code.
16+
</p>
17+
</recommendation>
18+
19+
<references>
20+
<li>
21+
<a href="https://blog.oversecured.com/Android-arbitrary-code-execution-via-third-party-package-contexts/">
22+
Oversecured (Android: arbitrary code execution via third-party package contexts)
23+
</a>
24+
</li>
25+
</references>
26+
27+
</qhelp>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @name Load 3rd party classes or code ('unsafe reflection') without signature check
3+
* @description Load classes or code from 3rd party package without checking the
4+
* package signature but only rely on package name.
5+
* This makes it susceptible to package namespace squatting
6+
* potentially leading to arbitrary code execution.
7+
* @kind path-problem
8+
* @problem.severity error
9+
* @precision high
10+
* @id java/unsafe-reflection
11+
* @tags security
12+
* experimental
13+
* external/cwe/cwe-470
14+
*/
15+
16+
import java
17+
import semmle.code.java.dataflow.DataFlow
18+
import semmle.code.java.dataflow.TaintTracking
19+
20+
predicate doesPackageContextLeadToInvokeMethod(
21+
DataFlow::Node sinkPackageContext, MethodAccess maInvoke
22+
23+
)
24+
{
25+
exists(
26+
MethodAccess maGetClassLoader,
27+
MethodAccess maLoadClass,
28+
MethodAccess maGetMethod |
29+
maGetClassLoader.getCallee().getName() = "getClassLoader" and
30+
maGetClassLoader.getQualifier() = sinkPackageContext.asExpr() and
31+
maLoadClass.getCallee().getName() = "loadClass" and
32+
maLoadClass.getQualifier() = maGetClassLoader and
33+
// check for arbitray code execution
34+
maGetMethod.getCallee().getName() = "getMethod" and
35+
maGetMethod.getQualifier() = maLoadClass and
36+
maInvoke.getCallee().getName() = "invoke" and
37+
maInvoke.getQualifier() = maGetMethod
38+
)
39+
}
40+
41+
predicate isSignaturesChecked(MethodAccess maCreatePackageContext)
42+
{
43+
exists(
44+
MethodAccess maCheckSignatures |
45+
maCheckSignatures.getCallee().getDeclaringType().getQualifiedName() = "android.content.pm.PackageManager" and
46+
maCheckSignatures.getCallee().getName() = "checkSignatures" and
47+
//maCheckSignatures.getArgument(0).toString() = maCreatePackageContext.getArgument(0).toString()
48+
TaintTracking::localTaint(
49+
DataFlow::exprNode(maCheckSignatures.getArgument(0)),
50+
DataFlow::exprNode(maCreatePackageContext.getArgument(0)))
51+
)
52+
}
53+
54+
from
55+
MethodAccess maCreatePackageContext,
56+
LocalVariableDeclExpr lvdePackageContext,
57+
DataFlow::Node sinkPackageContext,
58+
MethodAccess maInvoke
59+
where
60+
maCreatePackageContext.getCallee().getDeclaringType().getQualifiedName() = "android.content.ContextWrapper" and
61+
maCreatePackageContext.getCallee().getName() = "createPackageContext" and
62+
63+
not isSignaturesChecked(maCreatePackageContext) and
64+
65+
lvdePackageContext.getEnclosingStmt() = maCreatePackageContext.getEnclosingStmt() and
66+
TaintTracking::localTaint(DataFlow::exprNode(lvdePackageContext.getAnAccess()), sinkPackageContext) and
67+
68+
doesPackageContextLeadToInvokeMethod(sinkPackageContext, maInvoke)
69+
select
70+
lvdePackageContext,
71+
sinkPackageContext,
72+
maInvoke,
73+
maCreatePackageContext.getArgument(0)
74+

0 commit comments

Comments
 (0)