Skip to content

Commit 0e04f2b

Browse files
joefarebrotheratorralba
authored andcommitted
Add external storage souces
1 parent 0346b6b commit 0e04f2b

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ private module Frameworks {
8484
private import internal.ContainerFlow
8585
private import semmle.code.java.frameworks.android.Android
8686
private import semmle.code.java.frameworks.android.ContentProviders
87+
private import semmle.code.java.frameworks.android.ExternalStorage
8788
private import semmle.code.java.frameworks.android.Intent
8889
private import semmle.code.java.frameworks.android.Notifications
8990
private import semmle.code.java.frameworks.android.SharedPreferences

java/ql/lib/semmle/code/java/dataflow/FlowSources.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import semmle.code.java.frameworks.android.WebView
1717
import semmle.code.java.frameworks.JaxWS
1818
import semmle.code.java.frameworks.javase.WebSocket
1919
import semmle.code.java.frameworks.android.Android
20+
import semmle.code.java.frameworks.android.ExternalStorage
2021
import semmle.code.java.frameworks.android.OnActivityResultSource
2122
import semmle.code.java.frameworks.android.Intent
2223
import semmle.code.java.frameworks.play.Play
@@ -152,6 +153,12 @@ private class ThriftIfaceParameterSource extends RemoteFlowSource {
152153
override string getSourceType() { result = "Thrift Iface parameter" }
153154
}
154155

156+
private class AndroidExternalStorageSource extends RemoteFlowSource {
157+
AndroidExternalStorageSource() { androidExternalStorageSource(this) }
158+
159+
override string getSourceType() { result = "Android external storage" }
160+
}
161+
155162
/** Class for `tainted` user input. */
156163
abstract class UserInput extends DataFlow::Node { }
157164

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/** Provides definitions for working with uses of Android external storage */
2+
3+
import java
4+
import semmle.code.java.dataflow.DataFlow
5+
private import semmle.code.java.dataflow.ExternalFlow
6+
7+
private class ExternalStorageDirSourceModel extends SourceModelCsv {
8+
override predicate row(string row) {
9+
row =
10+
[
11+
//"package;type;overrides;name;signature;ext;spec;kind"
12+
"android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir",
13+
"android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir",
14+
"android.content;Context;true;getExternalCachesDir;(String);;ReturnValue;android-external-storage-dir",
15+
"android.content;Context;true;getExternalCachesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir",
16+
"android.os;Environment;false;getExternalStorageDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir",
17+
"android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir",
18+
]
19+
}
20+
}
21+
22+
private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
23+
DataFlow::localFlowStep(node1, node2)
24+
or
25+
exists(ConstructorCall c | c.getConstructedType() instanceof TypeFile |
26+
node1.asExpr() = c.getArgument(1) and
27+
node2.asExpr() = c
28+
)
29+
}
30+
31+
private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2) {
32+
externalStorageFlowStep*(node1, node2)
33+
}
34+
35+
/**
36+
* Holds if `n` is a node that reads the contents of an external file in Android.
37+
* This may be controlable by third-party applications, so is treated as a remote flow source.
38+
*/
39+
predicate androidExternalStorageSource(DataFlow::Node n) {
40+
exists(ConstructorCall fInp, DataFlow::Node externalDir |
41+
fInp.getConstructedType().hasQualifiedName("java.io", "FileInputStream") and
42+
n.asExpr() = fInp and
43+
sourceNode(externalDir, "android-external-storage-dir") and
44+
externalStorageFlow(externalDir, DataFlow::exprNode(fInp.getArgument(0)))
45+
)
46+
}

0 commit comments

Comments
 (0)