4
4
* Android configuration file and sensitive user data.
5
5
* @kind path-problem
6
6
* @id java/sensitive-android-file-leak
7
+ * @problem.severity warning
7
8
* @tags security
8
9
* external/cwe/cwe-200
9
10
*/
10
11
11
12
import java
13
+ import semmle.code.java.controlflow.Guards
12
14
import AndroidFileIntentSink
13
15
import AndroidFileIntentSource
14
- import DataFlow2:: PathGraph
15
- import semmle.code.java.dataflow.TaintTracking2
16
+ import DataFlow:: PathGraph
16
17
17
- private class StartsWithSanitizer extends DataFlow2 :: BarrierGuard {
18
+ private class StartsWithSanitizer extends DataFlow :: BarrierGuard {
18
19
StartsWithSanitizer ( ) { this .( MethodAccess ) .getMethod ( ) .hasName ( "startsWith" ) }
19
20
20
21
override predicate checks ( Expr e , boolean branch ) {
@@ -27,27 +28,32 @@ private class StartsWithSanitizer extends DataFlow2::BarrierGuard {
27
28
}
28
29
}
29
30
30
- class AndroidFileLeakConfig extends TaintTracking2 :: Configuration {
31
+ class AndroidFileLeakConfig extends TaintTracking :: Configuration {
31
32
AndroidFileLeakConfig ( ) { this = "AndroidFileLeakConfig" }
32
33
33
- /** Holds if it is an access to file intent result. */
34
- override predicate isSource ( DataFlow2:: Node src ) {
34
+ /**
35
+ * Holds if `src` is a read of some Intent-typed method argument guarded by a check like
36
+ * `requestCode == REQUEST_CODE__SELECT_CONTENT_FROM_APPS`, where `requestCode` is the first
37
+ * argument to `Activity.onActivityResult`.
38
+ */
39
+ override predicate isSource ( DataFlow:: Node src ) {
35
40
exists (
36
- AndroidActivityResultInput ai , AndroidFileIntentInput fi , IfStmt ifs , VarAccess intentVar // if (requestCode == REQUEST_CODE__SELECT_CONTENT_FROM_APPS)
41
+ AndroidActivityResultInput ai , AndroidFileIntentInput fi , ConditionBlock cb ,
42
+ VarAccess intentVar
37
43
|
38
- ifs .getCondition ( ) . getAChildExpr ( ) .getAChildExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) =
44
+ cb .getCondition ( ) .getAChildExpr ( ) .( CompileTimeConstantExpr ) .getIntValue ( ) =
39
45
fi .getRequestCode ( ) and
40
- ifs .getCondition ( ) . getAChildExpr ( ) .getAChildExpr ( ) = ai .getRequestCodeVar ( ) and
46
+ cb .getCondition ( ) .getAChildExpr ( ) = ai .getRequestCodeVar ( ) and
41
47
intentVar .getType ( ) instanceof TypeIntent and
42
- intentVar . ( Argument ) . getAnEnclosingStmt ( ) = ifs . getThen ( ) and
48
+ cb . getBasicBlock ( ) = intentVar . ( Argument ) . getAnEnclosingStmt ( ) and
43
49
src .asExpr ( ) = intentVar
44
50
)
45
51
}
46
52
47
53
/** Holds if it is a sink of file access in Android. */
48
- override predicate isSink ( DataFlow2 :: Node sink ) { sink instanceof AndroidFileSink }
54
+ override predicate isSink ( DataFlow :: Node sink ) { sink instanceof AndroidFileSink }
49
55
50
- override predicate isAdditionalTaintStep ( DataFlow2 :: Node prev , DataFlow2 :: Node succ ) {
56
+ override predicate isAdditionalTaintStep ( DataFlow :: Node prev , DataFlow :: Node succ ) {
51
57
exists ( MethodAccess aema , AsyncTaskRunInBackgroundMethod arm |
52
58
// fileAsyncTask.execute(params) will invoke doInBackground(params) of FileAsyncTask
53
59
aema .getQualifier ( ) .getType ( ) = arm .getDeclaringType ( ) and
@@ -60,18 +66,18 @@ class AndroidFileLeakConfig extends TaintTracking2::Configuration {
60
66
csma .getMethod ( ) instanceof ContextStartServiceMethod and
61
67
ce .getConstructedType ( ) instanceof TypeIntent and // Intent intent = new Intent(context, FileUploader.class);
62
68
ce .getArgument ( 1 ) .( TypeLiteral ) .getReferencedType ( ) = ssm .getDeclaringType ( ) and
63
- DataFlow2 :: localExprFlow ( ce , csma .getArgument ( 0 ) ) and // context.startService(intent);
69
+ DataFlow :: localExprFlow ( ce , csma .getArgument ( 0 ) ) and // context.startService(intent);
64
70
prev .asExpr ( ) = csma .getArgument ( 0 ) and
65
71
succ .asParameter ( ) = ssm .getParameter ( 0 ) // public int onStartCommand(Intent intent, int flags, int startId) {...} in FileUploader
66
72
)
67
73
}
68
74
69
- override predicate isSanitizerGuard ( DataFlow2 :: BarrierGuard guard ) {
75
+ override predicate isSanitizerGuard ( DataFlow :: BarrierGuard guard ) {
70
76
guard instanceof StartsWithSanitizer
71
77
}
72
78
}
73
79
74
- from DataFlow2 :: PathNode source , DataFlow2 :: PathNode sink , AndroidFileLeakConfig conf
80
+ from DataFlow :: PathNode source , DataFlow :: PathNode sink , AndroidFileLeakConfig conf
75
81
where conf .hasFlowPath ( source , sink )
76
82
select sink .getNode ( ) , source , sink , "Leaking arbitrary Android file from $@." , source .getNode ( ) ,
77
83
"this user input"
0 commit comments