@@ -17,53 +17,68 @@ import semmle.code.java.dataflow.TaintTracking2
1717private import semmle.code.java.dataflow.ExternalFlow
1818import DataFlow:: PathGraph
1919
20+ /** A string literal that represents the MIME type for Android APKs. */
2021class PackageArchiveMimeTypeLiteral extends StringLiteral {
2122 PackageArchiveMimeTypeLiteral ( ) { this .getValue ( ) = "application/vnd.android.package-archive" }
2223}
2324
25+ /** A method that sets the MIME type of an intent. */
2426class SetTypeMethod extends Method {
2527 SetTypeMethod ( ) {
2628 this .hasName ( [ "setType" , "setTypeAndNormalize" ] ) and
2729 this .getDeclaringType ( ) instanceof TypeIntent
2830 }
2931}
3032
33+ /** A method that sets the data URI and the MIME type of an intent. */
3134class SetDataAndTypeMethod extends Method {
3235 SetDataAndTypeMethod ( ) {
3336 this .hasName ( [ "setDataAndType" , "setDataAndTypeAndNormalize" ] ) and
3437 this .getDeclaringType ( ) instanceof TypeIntent
3538 }
3639}
3740
41+ /** A method that sets the data URI of an intent. */
3842class SetDataMethod extends Method {
3943 SetDataMethod ( ) {
4044 this .hasName ( [ "setData" , "setDataAndNormalize" , "setDataAndType" , "setDataAndTypeAndNormalize" ] ) and
4145 this .getDeclaringType ( ) instanceof TypeIntent
4246 }
4347}
4448
49+ /** A dataflow sink for the URI of an intent. */
4550class SetDataSink extends DataFlow:: ExprNode {
4651 SetDataSink ( ) { this .getExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof SetDataMethod }
4752}
4853
54+ /** A method that generates a URI. */
4955class UriConstructorMethod extends Method {
5056 UriConstructorMethod ( ) {
51- this .hasQualifiedName ( "android.net" , "Uri" , [ "parse" , "fromFile" , "fromParts" ] )
57+ this .hasQualifiedName ( "android.net" , "Uri" , [ "parse" , "fromFile" , "fromParts" ] ) or
58+ this .hasQualifiedName ( "androidx.core.content" , "FileProvider" , "getUriForFile" )
5259 }
5360}
5461
55- class ExternalSource extends DataFlow:: Node {
56- ExternalSource ( ) {
62+ /**
63+ * A dataflow source representing the URIs which an APK not controlled by the
64+ * application may come from. Incuding external storage and web URLs.
65+ */
66+ class ExternalAPKSource extends DataFlow:: Node {
67+ ExternalAPKSource ( ) {
5768 sourceNode ( this , "android-external-storage-dir" ) or
5869 this .asExpr ( ) .( MethodAccess ) .getMethod ( ) instanceof UriConstructorMethod or
5970 this .asExpr ( ) .( StringLiteral ) .getValue ( ) .matches ( [ "file://%" , "http://%" , "https://%" ] )
6071 }
6172}
6273
63- class ExternalSourceConfiguration extends DataFlow:: Configuration {
64- ExternalSourceConfiguration ( ) { this = "ExternalSourceConfiguration" }
74+ /**
75+ * A dataflow configuration for flow from an external source of an APK to the
76+ * `setData[AndType][AndNormalize]` method of an intent.
77+ */
78+ class APKConfiguration extends DataFlow:: Configuration {
79+ APKConfiguration ( ) { this = "APKConfiguration" }
6580
66- override predicate isSource ( DataFlow:: Node node ) { node instanceof ExternalSource }
81+ override predicate isSource ( DataFlow:: Node node ) { node instanceof ExternalAPKSource }
6782
6883 override predicate isSink ( DataFlow:: Node node ) {
6984 exists ( MethodAccess ma |
@@ -74,6 +89,10 @@ class ExternalSourceConfiguration extends DataFlow::Configuration {
7489 }
7590}
7691
92+ /**
93+ * A dataflow configuration tracking the flow of the Android APK MIME type to
94+ * the `setType` or `setTypeAndNormalize` method of an intent.
95+ */
7796private class PackageArchiveMimeTypeConfiguration extends TaintTracking2:: Configuration {
7897 PackageArchiveMimeTypeConfiguration ( ) { this = "PackageArchiveMimeTypeConfiguration" }
7998
@@ -105,6 +124,6 @@ private class PackageArchiveMimeTypeConfiguration extends TaintTracking2::Config
105124 }
106125}
107126
108- from DataFlow:: PathNode source , DataFlow:: PathNode sink , ExternalSourceConfiguration config
127+ from DataFlow:: PathNode source , DataFlow:: PathNode sink , APKConfiguration config
109128where config .hasFlowPath ( source , sink )
110129select sink .getNode ( ) , source , sink , "Arbitrary Android APK installation."
0 commit comments