3
3
* @description Getting file intent from user input without path validation could leak arbitrary
4
4
* Android configuration file and sensitive user data.
5
5
* @kind path-problem
6
- * @id java/sensitive_android_file_leak
6
+ * @id java/sensitive-android-file-leak
7
7
* @tags security
8
8
* external/cwe/cwe-200
9
9
*/
@@ -14,6 +14,19 @@ import AndroidFileIntentSource
14
14
import DataFlow2:: PathGraph
15
15
import semmle.code.java.dataflow.TaintTracking2
16
16
17
+ private class StartsWithSanitizer extends DataFlow2:: BarrierGuard {
18
+ StartsWithSanitizer ( ) { this .( MethodAccess ) .getMethod ( ) .hasName ( "startsWith" ) }
19
+
20
+ override predicate checks ( Expr e , boolean branch ) {
21
+ e =
22
+ [
23
+ this .( MethodAccess ) .getQualifier ( ) ,
24
+ this .( MethodAccess ) .getQualifier ( ) .( MethodAccess ) .getQualifier ( )
25
+ ] and
26
+ branch = false
27
+ }
28
+ }
29
+
17
30
class AndroidFileLeakConfig extends TaintTracking2:: Configuration {
18
31
AndroidFileLeakConfig ( ) { this = "AndroidFileLeakConfig" }
19
32
@@ -38,37 +51,23 @@ class AndroidFileLeakConfig extends TaintTracking2::Configuration {
38
51
exists ( MethodAccess aema , AsyncTaskRunInBackgroundMethod arm |
39
52
// fileAsyncTask.execute(params) will invoke doInBackground(params) of FileAsyncTask
40
53
aema .getQualifier ( ) .getType ( ) = arm .getDeclaringType ( ) and
41
- (
42
- aema .getMethod ( ) instanceof AsyncTaskExecuteMethod and
43
- prev .asExpr ( ) = aema .getArgument ( 0 )
44
- or
45
- aema .getMethod ( ) instanceof AsyncTaskExecuteOnExecutorMethod and
46
- prev .asExpr ( ) = aema .getArgument ( 1 )
47
- ) and
48
- succ .asExpr ( ) = arm .getParameter ( 0 ) .getAnAccess ( )
54
+ aema .getMethod ( ) instanceof ExecuteAsyncTaskMethod and
55
+ prev .asExpr ( ) = aema .getArgument ( aema .getMethod ( ) .( ExecuteAsyncTaskMethod ) .getParamIndex ( ) ) and
56
+ succ .asParameter ( ) = arm .getParameter ( 0 )
49
57
)
50
58
or
51
59
exists ( MethodAccess csma , ServiceOnStartCommandMethod ssm , ClassInstanceExpr ce |
52
60
csma .getMethod ( ) instanceof ContextStartServiceMethod and
53
61
ce .getConstructedType ( ) instanceof TypeIntent and // Intent intent = new Intent(context, FileUploader.class);
54
- ce .getArgument ( 1 ) .getType ( ) . ( ParameterizedType ) . getTypeArgument ( 0 ) = ssm .getDeclaringType ( ) and
62
+ ce .getArgument ( 1 ) .( TypeLiteral ) . getReferencedType ( ) = ssm .getDeclaringType ( ) and
55
63
DataFlow2:: localExprFlow ( ce , csma .getArgument ( 0 ) ) and // context.startService(intent);
56
64
prev .asExpr ( ) = csma .getArgument ( 0 ) and
57
- succ .asExpr ( ) = ssm .getParameter ( 0 ) . getAnAccess ( ) // public int onStartCommand(Intent intent, int flags, int startId) {...} in FileUploader
65
+ succ .asParameter ( ) = ssm .getParameter ( 0 ) // public int onStartCommand(Intent intent, int flags, int startId) {...} in FileUploader
58
66
)
59
67
}
60
68
61
- override predicate isSanitizer ( DataFlow2:: Node node ) {
62
- exists (
63
- MethodAccess startsWith // "startsWith" path check
64
- |
65
- startsWith .getMethod ( ) .hasName ( "startsWith" ) and
66
- (
67
- DataFlow2:: localExprFlow ( node .asExpr ( ) , startsWith .getQualifier ( ) ) or
68
- DataFlow2:: localExprFlow ( node .asExpr ( ) ,
69
- startsWith .getQualifier ( ) .( MethodAccess ) .getQualifier ( ) )
70
- )
71
- )
69
+ override predicate isSanitizerGuard ( DataFlow2:: BarrierGuard guard ) {
70
+ guard instanceof StartsWithSanitizer
72
71
}
73
72
}
74
73
0 commit comments