@@ -13,112 +13,42 @@ import semmle.code.java.security.ImplicitPendingIntents
1313class ImplicitPendingIntentStartConf extends TaintTracking:: Configuration {
1414 ImplicitPendingIntentStartConf ( ) { this = "ImplicitPendingIntentStartConf" }
1515
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 )
1818 }
1919
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+ }
2123
2224 override predicate isSanitizer ( DataFlow:: Node sanitizer ) {
2325 sanitizer instanceof ExplicitIntentSanitizer
2426 }
2527
2628 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 )
3337 }
3438
3539 override predicate allowImplicitRead ( DataFlow:: Node node , DataFlow:: Content c ) {
3640 super .allowImplicitRead ( node , c )
3741 or
38- this .isSink ( node ) and
42+ this .isSink ( node , _ ) and
3943 allowIntentExtrasImplicitRead ( node , c )
4044 or
4145 this .isAdditionalTaintStep ( node , _) and
4246 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- )
6647 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
8951 node .getType ( ) .( Array ) .getElementType ( ) instanceof TypeIntent and
9052 c instanceof DataFlow:: ArrayContent
9153 }
9254}
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