33 * @description Getting file intent from user input without path validation could leak arbitrary
44 * Android configuration file and sensitive user data.
55 * @kind path-problem
6- * @id java/sensitive_android_file_leak
6+ * @id java/sensitive-android-file-leak
77 * @tags security
88 * external/cwe/cwe-200
99 */
@@ -14,6 +14,19 @@ import AndroidFileIntentSource
1414import DataFlow2:: PathGraph
1515import semmle.code.java.dataflow.TaintTracking2
1616
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+
1730class AndroidFileLeakConfig extends TaintTracking2:: Configuration {
1831 AndroidFileLeakConfig ( ) { this = "AndroidFileLeakConfig" }
1932
@@ -38,37 +51,23 @@ class AndroidFileLeakConfig extends TaintTracking2::Configuration {
3851 exists ( MethodAccess aema , AsyncTaskRunInBackgroundMethod arm |
3952 // fileAsyncTask.execute(params) will invoke doInBackground(params) of FileAsyncTask
4053 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 )
4957 )
5058 or
5159 exists ( MethodAccess csma , ServiceOnStartCommandMethod ssm , ClassInstanceExpr ce |
5260 csma .getMethod ( ) instanceof ContextStartServiceMethod and
5361 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
5563 DataFlow2:: localExprFlow ( ce , csma .getArgument ( 0 ) ) and // context.startService(intent);
5664 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
5866 )
5967 }
6068
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
7271 }
7372}
7473
0 commit comments