@@ -21,21 +21,81 @@ import AutomodelEndpointTypes as AutomodelEndpointTypes
2121
2222newtype JavaRelatedLocationType = CallContext ( )
2323
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+
2450/**
2551 * A class representing nodes that are arguments to calls.
2652 */
27- private class ArgumentNode extends DataFlow:: Node {
28- Call c ;
53+ class ExplicitArgument extends ApplicationModeEndpoint , TExplicitArgument {
54+ Call call ;
55+ DataFlow:: Node arg ;
2956
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
3676 }
3777
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 ( ) }
3999}
40100
41101/**
@@ -47,7 +107,7 @@ private class ArgumentNode extends DataFlow::Node {
47107 */
48108module ApplicationCandidatesImpl implements SharedCharacteristics:: CandidateSig {
49109 // for documentation of the implementations here, see the QLDoc in the CandidateSig signature module.
50- class Endpoint = ArgumentNode ;
110+ class Endpoint = ApplicationModeEndpoint ;
51111
52112 class EndpointType = AutomodelEndpointTypes:: EndpointType ;
53113
@@ -61,18 +121,18 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
61121 predicate isSanitizer ( Endpoint e , EndpointType t ) {
62122 exists ( t ) and
63123 (
64- e .getType ( ) instanceof BoxedType
124+ e .asNode ( ) . getType ( ) instanceof BoxedType
65125 or
66- e .getType ( ) instanceof PrimitiveType
126+ e .asNode ( ) . getType ( ) instanceof PrimitiveType
67127 or
68- e .getType ( ) instanceof NumberType
128+ e .asNode ( ) . getType ( ) instanceof NumberType
69129 )
70130 or
71131 t instanceof AutomodelEndpointTypes:: PathInjectionSinkType and
72- e instanceof PathSanitizer:: PathInjectionSanitizer
132+ e . asNode ( ) instanceof PathSanitizer:: PathInjectionSanitizer
73133 }
74134
75- RelatedLocation asLocation ( Endpoint e ) { result = e .asExpr ( ) }
135+ RelatedLocation asLocation ( Endpoint e ) { result = e .asTop ( ) }
76136
77137 predicate isKnownKind = AutomodelJavaUtil:: isKnownKind / 2 ;
78138
@@ -98,16 +158,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
98158 ApplicationModeGetCallable:: getCallable ( e ) .hasQualifiedName ( package , type , name ) and
99159 signature = ExternalFlow:: paramsString ( ApplicationModeGetCallable:: getCallable ( e ) ) and
100160 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 ( ) )
111162 }
112163
113164 /**
@@ -118,7 +169,7 @@ module ApplicationCandidatesImpl implements SharedCharacteristics::CandidateSig
118169 */
119170 RelatedLocation getRelatedLocation ( Endpoint e , RelatedLocationType type ) {
120171 type = CallContext ( ) and
121- result = any ( Call c | e . asExpr ( ) = [ c . getAnArgument ( ) , c . getQualifier ( ) ] )
172+ result = e . asTop ( )
122173 }
123174}
124175
@@ -132,20 +183,15 @@ private module ApplicationModeGetCallable implements AutomodelSharedGetCallable:
132183 /**
133184 * Returns the API callable being modeled.
134185 */
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 ( ) }
141187}
142188
143189/**
144190 * Contains endpoints that are defined in QL code rather than as a MaD model. Ideally this predicate
145191 * should be empty.
146192 */
147193private predicate isCustomSink ( Endpoint e , string kind ) {
148- e instanceof QueryInjectionSink and kind = "sql"
194+ e . asNode ( ) instanceof QueryInjectionSink and kind = "sql"
149195}
150196
151197module CharacteristicsImpl =
@@ -169,14 +215,9 @@ class ApplicationModeMetadataExtractor extends string {
169215 Endpoint e , string package , string type , string subtypes , string name , string signature ,
170216 string input
171217 ) {
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
180221 package = callable .getDeclaringType ( ) .getPackage ( ) .getName ( ) and
181222 // we're using the erased types because the MaD convention is to not specify type parameters.
182223 // 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
253294 IsMaDTaintStepCharacteristic ( ) { this = "taint step" }
254295
255296 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 ( ) , _, _, _)
278301 }
279302}
280303
@@ -351,7 +374,7 @@ private class OtherArgumentToModeledMethodCharacteristic extends Characteristics
351374private class FunctionValueCharacteristic extends CharacteristicsImpl:: LikelyNotASinkCharacteristic {
352375 FunctionValueCharacteristic ( ) { this = "function value" }
353376
354- override predicate appliesToEndpoint ( Endpoint e ) { e .asExpr ( ) instanceof FunctionalExpr }
377+ override predicate appliesToEndpoint ( Endpoint e ) { e .asNode ( ) . asExpr ( ) instanceof FunctionalExpr }
355378}
356379
357380/**
@@ -371,12 +394,12 @@ private class CannotBeTaintedCharacteristic extends CharacteristicsImpl::LikelyN
371394 * Holds if the node `n` is known as the predecessor in a modeled flow step.
372395 */
373396 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 ( ) , _)
380403 }
381404}
382405
0 commit comments