@@ -21,21 +21,81 @@ import AutomodelEndpointTypes as AutomodelEndpointTypes
21
21
22
22
newtype JavaRelatedLocationType = CallContext ( )
23
23
24
+ newtype TApplicationModeEndpoint =
25
+ TExplicitArgument ( Call call , DataFlow:: Node arg ) {
26
+ exists ( Argument argExpr |
27
+ arg .asExpr ( ) = argExpr and not argExpr .isVararg ( ) and call = argExpr .getCall ( )
28
+ )
29
+ } or
30
+ TInstanceArgument ( Call call , DataFlow:: Node arg ) { arg = DataFlow:: getInstanceArgument ( call ) } or
31
+ TImplicitVarargsArray ( Call call , DataFlow:: ImplicitVarargsArray varargs , int idx ) {
32
+ varargs .getCall ( ) = call and
33
+ idx = min ( Argument arg , int n | arg = call .getArgument ( n ) and arg .isVararg ( ) | n )
34
+ }
35
+
36
+ abstract private class ApplicationModeEndpoint extends TApplicationModeEndpoint {
37
+ abstract predicate isArgOf ( Call c , int idx ) ;
38
+
39
+ Call getCall ( ) { this .isArgOf ( result , _) }
40
+
41
+ int getArgIndex ( ) { this .isArgOf ( _, result ) }
42
+
43
+ abstract Top asTop ( ) ;
44
+
45
+ abstract DataFlow:: Node asNode ( ) ;
46
+
47
+ abstract string toString ( ) ;
48
+ }
49
+
24
50
/**
25
51
* A class representing nodes that are arguments to calls.
26
52
*/
27
- private class ArgumentNode extends DataFlow:: Node {
28
- Call c ;
53
+ class ExplicitArgument extends ApplicationModeEndpoint , TExplicitArgument {
54
+ Call call ;
55
+ DataFlow:: Node arg ;
29
56
30
- ArgumentNode ( ) {
31
- exists ( Argument arg | this .asExpr ( ) = arg and not arg .isVararg ( ) and c = arg .getCall ( ) )
32
- or
33
- this .( DataFlow:: ImplicitVarargsArray ) .getCall ( ) = c
34
- or
35
- this = DataFlow:: getInstanceArgument ( c )
57
+ ExplicitArgument ( ) { this = TExplicitArgument ( call , arg ) }
58
+
59
+ override predicate isArgOf ( Call c , int idx ) { c = call and this .asTop ( ) = c .getArgument ( idx ) }
60
+
61
+ override Top asTop ( ) { result = arg .asExpr ( ) }
62
+
63
+ override DataFlow:: Node asNode ( ) { result = arg }
64
+
65
+ override string toString ( ) { result = arg .toString ( ) }
66
+ }
67
+
68
+ class InstanceArgument extends ApplicationModeEndpoint , TInstanceArgument {
69
+ Call call ;
70
+ DataFlow:: Node arg ;
71
+
72
+ InstanceArgument ( ) { this = TInstanceArgument ( call , arg ) }
73
+
74
+ override predicate isArgOf ( Call c , int idx ) {
75
+ c = call and this .asTop ( ) = c .getQualifier ( ) and idx = - 1
36
76
}
37
77
38
- Call getCall ( ) { result = c }
78
+ override Top asTop ( ) { if exists ( arg .asExpr ( ) ) then result = arg .asExpr ( ) else result = call }
79
+
80
+ override DataFlow:: Node asNode ( ) { result = arg }
81
+
82
+ override string toString ( ) { result = arg .toString ( ) }
83
+ }
84
+
85
+ class ImplicitVarargsArray extends ApplicationModeEndpoint , TImplicitVarargsArray {
86
+ Call call ;
87
+ DataFlow:: ImplicitVarargsArray varargs ;
88
+ int idx ;
89
+
90
+ ImplicitVarargsArray ( ) { this = TImplicitVarargsArray ( call , varargs , idx ) }
91
+
92
+ override predicate isArgOf ( Call c , int i ) { c = call and i = idx }
93
+
94
+ override Top asTop ( ) { result = this .getCall ( ) }
95
+
96
+ override DataFlow:: Node asNode ( ) { result = varargs }
97
+
98
+ override string toString ( ) { result = varargs .toString ( ) }
39
99
}
40
100
41
101
/**
@@ -47,7 +107,7 @@ private class ArgumentNode extends DataFlow::Node {
47
107
*/
48
108
module ApplicationCandidatesImpl implements SharedCharacteristics:: CandidateSig {
49
109
// for documentation of the implementations here, see the QLDoc in the CandidateSig signature module.
50
- class Endpoint = ArgumentNode ;
110
+ class Endpoint = ApplicationModeEndpoint ;
51
111
52
112
class EndpointType = AutomodelEndpointTypes:: EndpointType ;
53
113
@@ -61,18 +121,18 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
61
121
predicate isSanitizer ( Endpoint e , EndpointType t ) {
62
122
exists ( t ) and
63
123
(
64
- e .getType ( ) instanceof BoxedType
124
+ e .asNode ( ) . getType ( ) instanceof BoxedType
65
125
or
66
- e .getType ( ) instanceof PrimitiveType
126
+ e .asNode ( ) . getType ( ) instanceof PrimitiveType
67
127
or
68
- e .getType ( ) instanceof NumberType
128
+ e .asNode ( ) . getType ( ) instanceof NumberType
69
129
)
70
130
or
71
131
t instanceof AutomodelEndpointTypes:: PathInjectionSinkType and
72
- e instanceof PathSanitizer:: PathInjectionSanitizer
132
+ e . asNode ( ) instanceof PathSanitizer:: PathInjectionSanitizer
73
133
}
74
134
75
- RelatedLocation asLocation ( Endpoint e ) { result = e .asExpr ( ) }
135
+ RelatedLocation asLocation ( Endpoint e ) { result = e .asTop ( ) }
76
136
77
137
predicate isKnownKind = AutomodelJavaUtil:: isKnownKind / 2 ;
78
138
@@ -98,16 +158,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
98
158
ApplicationModeGetCallable:: getCallable ( e ) .hasQualifiedName ( package , type , name ) and
99
159
signature = ExternalFlow:: paramsString ( ApplicationModeGetCallable:: getCallable ( e ) ) and
100
160
ext = "" and
101
- (
102
- exists ( Call c , int argIdx |
103
- e .asExpr ( ) = c .getArgument ( argIdx ) and
104
- input = AutomodelJavaUtil:: getArgumentForIndex ( argIdx )
105
- )
106
- or
107
- exists ( Call c |
108
- e .asExpr ( ) = c .getQualifier ( ) and input = AutomodelJavaUtil:: getArgumentForIndex ( - 1 )
109
- )
110
- )
161
+ input = AutomodelJavaUtil:: getArgumentForIndex ( e .getArgIndex ( ) )
111
162
}
112
163
113
164
/**
@@ -118,7 +169,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
118
169
*/
119
170
RelatedLocation getRelatedLocation ( Endpoint e , RelatedLocationType type ) {
120
171
type = CallContext ( ) and
121
- result = any ( Call c | e . asExpr ( ) = [ c . getAnArgument ( ) , c . getQualifier ( ) ] )
172
+ result = e . asTop ( )
122
173
}
123
174
}
124
175
@@ -132,20 +183,15 @@ private module ApplicationModeGetCallable implements AutomodelSharedGetCallable:
132
183
/**
133
184
* Returns the API callable being modeled.
134
185
*/
135
- Callable getCallable ( Endpoint e ) {
136
- exists ( Call c |
137
- e .asExpr ( ) = [ c .getAnArgument ( ) , c .getQualifier ( ) ] and
138
- result = c .getCallee ( )
139
- )
140
- }
186
+ Callable getCallable ( Endpoint e ) { result = e .getCall ( ) .getCallee ( ) }
141
187
}
142
188
143
189
/**
144
190
* Contains endpoints that are defined in QL code rather than as a MaD model. Ideally this predicate
145
191
* should be empty.
146
192
*/
147
193
private predicate isCustomSink ( Endpoint e , string kind ) {
148
- e instanceof QueryInjectionSink and kind = "sql"
194
+ e . asNode ( ) instanceof QueryInjectionSink and kind = "sql"
149
195
}
150
196
151
197
module CharacteristicsImpl =
@@ -169,14 +215,9 @@ class ApplicationModeMetadataExtractor extends string {
169
215
Endpoint e , string package , string type , string subtypes , string name , string signature ,
170
216
string input
171
217
) {
172
- exists ( Call call , Callable callable , int argIdx |
173
- call .getCallee ( ) = callable and
174
- (
175
- e .asExpr ( ) = call .getArgument ( argIdx )
176
- or
177
- e .asExpr ( ) = call .getQualifier ( ) and argIdx = - 1
178
- ) and
179
- input = AutomodelJavaUtil:: getArgumentForIndex ( argIdx ) and
218
+ exists ( Callable callable |
219
+ e .getCall ( ) .getCallee ( ) = callable and
220
+ input = AutomodelJavaUtil:: getArgumentForIndex ( e .getArgIndex ( ) ) and
180
221
package = callable .getDeclaringType ( ) .getPackage ( ) .getName ( ) and
181
222
// we're using the erased types because the MaD convention is to not specify type parameters.
182
223
// Whether something is or isn't a sink doesn't usually depend on the type parameters.
@@ -253,28 +294,10 @@ private class IsMaDTaintStepCharacteristic extends CharacteristicsImpl::NotASink
253
294
IsMaDTaintStepCharacteristic ( ) { this = "taint step" }
254
295
255
296
override predicate appliesToEndpoint ( Endpoint e ) {
256
- FlowSummaryImpl:: Private:: Steps:: summaryThroughStepValue ( e , _, _) or
257
- FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( e , _, _) or
258
- FlowSummaryImpl:: Private:: Steps:: summaryGetterStep ( e , _, _, _) or
259
- FlowSummaryImpl:: Private:: Steps:: summarySetterStep ( e , _, _, _)
260
- }
261
- }
262
-
263
- /**
264
- * A negative characteristic that filters out qualifiers that are classes (i.e. static calls). These
265
- * are unlikely to have any non-trivial flow going into them.
266
- *
267
- * Technically, an accessed type _could_ come from outside of the source code, but there's not
268
- * much likelihood of that being user-controlled.
269
- */
270
- private class ClassQualifierCharacteristic extends CharacteristicsImpl:: NotASinkCharacteristic {
271
- ClassQualifierCharacteristic ( ) { this = "class qualifier" }
272
-
273
- override predicate appliesToEndpoint ( Endpoint e ) {
274
- exists ( Call c |
275
- e .asExpr ( ) = c .getQualifier ( ) and
276
- c .getQualifier ( ) instanceof TypeAccess
277
- )
297
+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepValue ( e .asNode ( ) , _, _) or
298
+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( e .asNode ( ) , _, _) or
299
+ FlowSummaryImpl:: Private:: Steps:: summaryGetterStep ( e .asNode ( ) , _, _, _) or
300
+ FlowSummaryImpl:: Private:: Steps:: summarySetterStep ( e .asNode ( ) , _, _, _)
278
301
}
279
302
}
280
303
@@ -351,7 +374,7 @@ private class OtherArgumentToModeledMethodCharacteristic extends Characteristics
351
374
private class FunctionValueCharacteristic extends CharacteristicsImpl:: LikelyNotASinkCharacteristic {
352
375
FunctionValueCharacteristic ( ) { this = "function value" }
353
376
354
- override predicate appliesToEndpoint ( Endpoint e ) { e .asExpr ( ) instanceof FunctionalExpr }
377
+ override predicate appliesToEndpoint ( Endpoint e ) { e .asNode ( ) . asExpr ( ) instanceof FunctionalExpr }
355
378
}
356
379
357
380
/**
@@ -371,12 +394,12 @@ private class CannotBeTaintedCharacteristic extends CharacteristicsImpl::LikelyN
371
394
* Holds if the node `n` is known as the predecessor in a modeled flow step.
372
395
*/
373
396
private predicate isKnownOutNodeForStep ( Endpoint e ) {
374
- e .asExpr ( ) instanceof Call or // we just assume flow in that case
375
- TaintTracking:: localTaintStep ( _, e ) or
376
- FlowSummaryImpl:: Private:: Steps:: summaryThroughStepValue ( _, e , _) or
377
- FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( _, e , _) or
378
- FlowSummaryImpl:: Private:: Steps:: summaryGetterStep ( _, _, e , _) or
379
- FlowSummaryImpl:: Private:: Steps:: summarySetterStep ( _, _, e , _)
397
+ e .asNode ( ) . asExpr ( ) instanceof Call or // we just assume flow in that case
398
+ TaintTracking:: localTaintStep ( _, e . asNode ( ) ) or
399
+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepValue ( _, e . asNode ( ) , _) or
400
+ FlowSummaryImpl:: Private:: Steps:: summaryThroughStepTaint ( _, e . asNode ( ) , _) or
401
+ FlowSummaryImpl:: Private:: Steps:: summaryGetterStep ( _, _, e . asNode ( ) , _) or
402
+ FlowSummaryImpl:: Private:: Steps:: summarySetterStep ( _, _, e . asNode ( ) , _)
380
403
}
381
404
}
382
405
0 commit comments