@@ -13,112 +13,42 @@ import semmle.code.java.security.ImplicitPendingIntents
13
13
class ImplicitPendingIntentStartConf extends TaintTracking:: Configuration {
14
14
ImplicitPendingIntentStartConf ( ) { this = "ImplicitPendingIntentStartConf" }
15
15
16
- override predicate isSource ( DataFlow:: Node source ) {
17
- source .asExpr ( ) instanceof ImplicitPendingIntentCreation
16
+ override predicate isSource ( DataFlow:: Node source , DataFlow :: FlowState state ) {
17
+ source .( ImplicitPendingIntentSource ) . hasState ( state )
18
18
}
19
19
20
- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof SendPendingIntent }
20
+ override predicate isSink ( DataFlow:: Node sink , DataFlow:: FlowState state ) {
21
+ sink .( ImplicitPendingIntentSink ) .hasState ( state )
22
+ }
21
23
22
24
override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
23
25
sanitizer instanceof ExplicitIntentSanitizer
24
26
}
25
27
26
28
override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
27
- exists ( Field f |
28
- f .getType ( ) instanceof PendingIntent and
29
- node1 .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) =
30
- DataFlow:: getFieldQualifier ( f .getAnAccess ( ) .( FieldWrite ) ) and
31
- node2 .asExpr ( ) .( FieldRead ) .getField ( ) = f
32
- )
29
+ any ( ImplicitPendingIntentAdditionalTaintStep c ) .step ( node1 , node2 )
30
+ }
31
+
32
+ override predicate isAdditionalFlowStep (
33
+ DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
34
+ DataFlow:: FlowState state2
35
+ ) {
36
+ any ( ImplicitPendingIntentAdditionalTaintStep c ) .step ( node1 , state1 , node2 , state2 )
33
37
}
34
38
35
39
override predicate allowImplicitRead ( DataFlow:: Node node , DataFlow:: Content c ) {
36
40
super .allowImplicitRead ( node , c )
37
41
or
38
- this .isSink ( node ) and
42
+ this .isSink ( node , _ ) and
39
43
allowIntentExtrasImplicitRead ( node , c )
40
44
or
41
45
this .isAdditionalTaintStep ( node , _) and
42
46
c .( DataFlow:: FieldContent ) .getType ( ) instanceof PendingIntent
43
- }
44
- }
45
-
46
- private class ImplicitPendingIntentCreation extends Expr {
47
- ImplicitPendingIntentCreation ( ) {
48
- exists ( Argument arg |
49
- this .getType ( ) instanceof PendingIntent and
50
- exists ( ImplicitPendingIntentConf conf | conf .hasFlowTo ( DataFlow:: exprNode ( arg ) ) ) and
51
- arg .getCall ( ) = this
52
- )
53
- }
54
- }
55
-
56
- private class SendPendingIntent extends DataFlow:: Node {
57
- SendPendingIntent ( ) {
58
- sinkNode ( this , "intent-start" ) and
59
- // implicit intents can't be started as services since API 21
60
- not exists ( MethodAccess ma , Method m |
61
- ma .getMethod ( ) = m and
62
- m .getDeclaringType ( ) .getASupertype * ( ) instanceof TypeContext and
63
- m .getName ( ) .matches ( [ "start%Service%" , "bindService%" ] ) and
64
- this .asExpr ( ) = ma .getArgument ( 0 )
65
- )
66
47
or
67
- sinkNode ( this , "pending-intent-sent" )
68
- }
69
- }
70
-
71
- private class ImplicitPendingIntentConf extends DataFlow2:: Configuration {
72
- ImplicitPendingIntentConf ( ) { this = "PendingIntentConf" }
73
-
74
- override predicate isSource ( DataFlow:: Node source ) {
75
- exists ( ClassInstanceExpr cc |
76
- cc .getConstructedType ( ) instanceof TypeIntent and source .asExpr ( ) = cc
77
- )
78
- }
79
-
80
- override predicate isSink ( DataFlow:: Node sink ) { sink instanceof MutablePendingIntentSink }
81
-
82
- override predicate isBarrier ( DataFlow:: Node barrier ) {
83
- barrier instanceof ExplicitIntentSanitizer
84
- }
85
-
86
- override predicate allowImplicitRead ( DataFlow:: Node node , DataFlow:: Content c ) {
87
- // Allow implicit reads of Intent arrays for sinks like getStartActivities
88
- isSink ( node ) and
48
+ // Allow implicit reads of Intent arrays for steps like getActivities
49
+ // or sinks like startActivities
50
+ ( this .isSink ( node , _) or this .isAdditionalFlowStep ( node , _, _, _) ) and
89
51
node .getType ( ) .( Array ) .getElementType ( ) instanceof TypeIntent and
90
52
c instanceof DataFlow:: ArrayContent
91
53
}
92
54
}
93
-
94
- private class PendingIntentSink extends DataFlow:: Node {
95
- PendingIntentSink ( ) { sinkNode ( this , "pending-intent" ) }
96
- }
97
-
98
- private class MutablePendingIntentSink extends PendingIntentSink {
99
- MutablePendingIntentSink ( ) {
100
- exists ( Argument flagArg | flagArg = this .asExpr ( ) .( Argument ) .getCall ( ) .getArgument ( 3 ) |
101
- // API < 31, PendingIntents are mutable by default
102
- not TaintTracking:: localExprTaint ( any ( ImmutablePendingIntentFlag flag ) .getAnAccess ( ) , flagArg )
103
- or
104
- // API >= 31, PendingIntents need to explicitly set mutability
105
- TaintTracking:: localExprTaint ( any ( MutablePendingIntentFlag flag ) .getAnAccess ( ) , flagArg )
106
- )
107
- }
108
- }
109
-
110
- private class PendingIntentFlag extends Field {
111
- PendingIntentFlag ( ) {
112
- this .getDeclaringType ( ) instanceof PendingIntent and
113
- this .isPublic ( ) and
114
- this .getName ( ) .matches ( "FLAG_%" )
115
- }
116
- }
117
-
118
- private class ImmutablePendingIntentFlag extends PendingIntentFlag {
119
- ImmutablePendingIntentFlag ( ) { this .hasName ( "FLAG_IMMUTABLE" ) }
120
- }
121
-
122
- private class MutablePendingIntentFlag extends PendingIntentFlag {
123
- MutablePendingIntentFlag ( ) { this .hasName ( "FLAG_MUTABLE" ) }
124
- }
0 commit comments