Skip to content

Commit 5f4e8e3

Browse files
committed
Add test cases relating to intents with the ACTION_INSTALL_PACKAGE action
1 parent f03e90f commit 5f4e8e3

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

java/ql/src/Security/CWE/CWE-094/ArbitraryAPKInstallation.ql

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import java
1414
import semmle.code.java.frameworks.android.Intent
1515
import semmle.code.java.dataflow.DataFlow
1616
import semmle.code.java.dataflow.TaintTracking2
17+
import semmle.code.java.dataflow.TaintTracking3
1718
private import semmle.code.java.dataflow.ExternalFlow
1819
import DataFlow::PathGraph
1920

@@ -22,6 +23,17 @@ class PackageArchiveMimeTypeLiteral extends StringLiteral {
2223
PackageArchiveMimeTypeLiteral() { this.getValue() = "application/vnd.android.package-archive" }
2324
}
2425

26+
class InstallPackageAction extends Expr {
27+
InstallPackageAction() {
28+
this.(StringLiteral).getValue() = "android.intent.action.INSTALL_PACKAGE"
29+
or
30+
exists(VarAccess va |
31+
va.getVariable().hasName("ACTION_INSTALL_PACKAGE") and
32+
va.getQualifier().getType() instanceof TypeIntent
33+
)
34+
}
35+
}
36+
2537
/** A method that sets the MIME type of an intent. */
2638
class SetTypeMethod extends Method {
2739
SetTypeMethod() {
@@ -48,7 +60,12 @@ class SetDataMethod extends Method {
4860

4961
/** A dataflow sink for the URI of an intent. */
5062
class SetDataSink extends DataFlow::ExprNode {
51-
SetDataSink() { this.getExpr().(MethodAccess).getMethod() instanceof SetDataMethod }
63+
SetDataSink() {
64+
exists(MethodAccess ma |
65+
this.getExpr() = ma.getQualifier() and
66+
ma.getMethod() instanceof SetDataMethod
67+
)
68+
}
5269
}
5370

5471
/** A method that generates a URI. */
@@ -84,14 +101,44 @@ class ApkConfiguration extends DataFlow::Configuration {
84101
exists(MethodAccess ma |
85102
ma.getMethod() instanceof SetDataMethod and
86103
ma.getArgument(0) = node.asExpr() and
87-
any(PackageArchiveMimeTypeConfiguration c).hasFlowToExpr(ma)
104+
(
105+
any(PackageArchiveMimeTypeConfiguration c).hasFlowToExpr(ma.getQualifier())
106+
or
107+
any(InstallPackageActionConfiguration c).hasFlowToExpr(ma.getQualifier())
108+
)
88109
)
89110
}
90111
}
91112

113+
private class InstallPackageActionConfiguration extends TaintTracking3::Configuration {
114+
InstallPackageActionConfiguration() { this = "InstallPackageActionConfiguration" }
115+
116+
override predicate isSource(DataFlow::Node source) {
117+
source.asExpr() instanceof InstallPackageAction
118+
}
119+
120+
override predicate isAdditionalTaintStep(
121+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
122+
DataFlow::FlowState state2
123+
) {
124+
state1 instanceof DataFlow::FlowStateEmpty and
125+
state2 = "hasPackageInstallAction" and
126+
exists(ConstructorCall cc |
127+
cc.getConstructedType() instanceof TypeIntent and
128+
node1.asExpr() = cc.getArgument(0) and
129+
node2.asExpr() = cc
130+
)
131+
}
132+
133+
override predicate isSink(DataFlow::Node node, DataFlow::FlowState state) {
134+
state = "hasPackageInstallAction" and node.asExpr().getType() instanceof TypeIntent
135+
}
136+
}
137+
92138
/**
93139
* A dataflow configuration tracking the flow of the Android APK MIME type to
94-
* the `setType` or `setTypeAndNormalize` method of an intent.
140+
* the `setType` or `setTypeAndNormalize` method of an intent, followed by a call
141+
* to `setData[AndType][AndNormalize]`.
95142
*/
96143
private class PackageArchiveMimeTypeConfiguration extends TaintTracking2::Configuration {
97144
PackageArchiveMimeTypeConfiguration() { this = "PackageArchiveMimeTypeConfiguration" }

java/ql/test/query-tests/security/CWE-094/APKInstallation.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ nodes
55
| APKInstallation.java:29:24:29:38 | parse(...) | semmle.label | parse(...) |
66
| APKInstallation.java:36:24:36:51 | fromFile(...) | semmle.label | fromFile(...) |
77
| APKInstallation.java:43:31:43:48 | fromFile(...) | semmle.label | fromFile(...) |
8+
| APKInstallation.java:50:24:50:41 | fromFile(...) | semmle.label | fromFile(...) |
9+
| APKInstallation.java:57:24:57:41 | fromFile(...) | semmle.label | fromFile(...) |
810
subpaths
911
#select
1012
| APKInstallation.java:14:31:14:58 | fromFile(...) | APKInstallation.java:14:31:14:58 | fromFile(...) | APKInstallation.java:14:31:14:58 | fromFile(...) | Arbitrary Android APK installation. |
1113
| APKInstallation.java:21:31:21:44 | parse(...) | APKInstallation.java:21:31:21:44 | parse(...) | APKInstallation.java:21:31:21:44 | parse(...) | Arbitrary Android APK installation. |
1214
| APKInstallation.java:29:24:29:38 | parse(...) | APKInstallation.java:29:24:29:38 | parse(...) | APKInstallation.java:29:24:29:38 | parse(...) | Arbitrary Android APK installation. |
1315
| APKInstallation.java:36:24:36:51 | fromFile(...) | APKInstallation.java:36:24:36:51 | fromFile(...) | APKInstallation.java:36:24:36:51 | fromFile(...) | Arbitrary Android APK installation. |
1416
| APKInstallation.java:43:31:43:48 | fromFile(...) | APKInstallation.java:43:31:43:48 | fromFile(...) | APKInstallation.java:43:31:43:48 | fromFile(...) | Arbitrary Android APK installation. |
17+
| APKInstallation.java:50:24:50:41 | fromFile(...) | APKInstallation.java:50:24:50:41 | fromFile(...) | APKInstallation.java:50:24:50:41 | fromFile(...) | Arbitrary Android APK installation. |
18+
| APKInstallation.java:57:24:57:41 | fromFile(...) | APKInstallation.java:57:24:57:41 | fromFile(...) | APKInstallation.java:57:24:57:41 | fromFile(...) | Arbitrary Android APK installation. |

java/ql/test/query-tests/security/CWE-094/APKInstallation.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,18 @@ public void installAPK4(String path) {
4343
intent.setDataAndType(Uri.fromFile(file), APK_MIMETYPE);
4444
startActivity(intent);
4545
}
46+
47+
public void installAPK5(String path) {
48+
File file = new File(Environment.getExternalStorageDirectory(), path);
49+
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
50+
intent.setData(Uri.fromFile(file));
51+
startActivity(intent);
52+
}
53+
54+
public void installAPK6(String path) {
55+
File file = new File(Environment.getExternalStorageDirectory(), path);
56+
Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
57+
intent.setData(Uri.fromFile(file));
58+
startActivity(intent);
59+
}
4660
}

0 commit comments

Comments
 (0)