55
66private import CaptureModelsSpecific
77
8- class ActiveConfiguration extends Unit {
9- predicate activateThroughFlowConfig ( ) { none ( ) }
10-
11- predicate activateFromSourceConfig ( ) { none ( ) }
12-
13- predicate activateToSinkConfig ( ) { none ( ) }
14- }
15-
168class DataFlowTargetApi extends TargetApiSpecific {
179 DataFlowTargetApi ( ) { isRelevantForDataFlowModels ( this ) }
1810}
@@ -46,6 +38,20 @@ private predicate isRelevantContent(DataFlow::Content c) {
4638 DataFlowPrivate:: containerContent ( c )
4739}
4840
41+ /**
42+ * Gets the MaD string representation of the parameter node `p`.
43+ */
44+ string parameterNodeAsInput ( DataFlow:: ParameterNode p ) {
45+ result = parameterAccess ( p .asParameter ( ) )
46+ or
47+ result = qualifierString ( ) and p instanceof InstanceParameterNode
48+ }
49+
50+ /**
51+ * Gets the MaD input string representation of `source`.
52+ */
53+ string asInputArgument ( DataFlow:: Node source ) { result = asInputArgumentSpecific ( source ) }
54+
4955/**
5056 * Gets the summary model for `api` with `input`, `output` and `kind`.
5157 */
@@ -111,61 +117,70 @@ string captureQualifierFlow(TargetApiSpecific api) {
111117
112118private int accessPathLimit ( ) { result = 2 }
113119
120+ private newtype TTaintState =
121+ TTaintRead ( int n ) { n in [ 0 .. accessPathLimit ( ) ] } or
122+ TTaintStore ( int n ) { n in [ 1 .. accessPathLimit ( ) ] }
123+
124+ abstract private class TaintState extends TTaintState {
125+ abstract string toString ( ) ;
126+ }
127+
114128/**
115129 * A FlowState representing a tainted read.
116130 */
117- private class TaintRead extends DataFlow :: FlowState {
131+ private class TaintRead extends TaintState , TTaintRead {
118132 private int step ;
119133
120- TaintRead ( ) { this = "TaintRead(" + step + ")" and step in [ 0 .. accessPathLimit ( ) ] }
134+ TaintRead ( ) { this = TTaintRead ( step ) }
121135
122136 /**
123137 * Gets the flow state step number.
124138 */
125139 int getStep ( ) { result = step }
140+
141+ override string toString ( ) { result = "TaintRead(" + step + ")" }
126142}
127143
128144/**
129145 * A FlowState representing a tainted write.
130146 */
131- private class TaintStore extends DataFlow :: FlowState {
147+ private class TaintStore extends TaintState , TTaintStore {
132148 private int step ;
133149
134- TaintStore ( ) { this = "TaintStore(" + step + ")" and step in [ 1 .. accessPathLimit ( ) ] }
150+ TaintStore ( ) { this = TTaintStore ( step ) }
135151
136152 /**
137153 * Gets the flow state step number.
138154 */
139155 int getStep ( ) { result = step }
156+
157+ override string toString ( ) { result = "TaintStore(" + step + ")" }
140158}
141159
142160/**
143- * A TaintTracking Configuration used for tracking flow through APIs.
161+ * A data-flow configuration for tracking flow through APIs.
144162 * The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters.
145163 *
146164 * This can be used to generate Flow summaries for APIs from parameter to return.
147165 */
148- private class ThroughFlowConfig extends TaintTracking:: Configuration {
149- ThroughFlowConfig ( ) {
150- this = "ThroughFlowConfig" and any ( ActiveConfiguration ac ) .activateThroughFlowConfig ( )
151- }
166+ module ThroughFlowConfig implements DataFlow:: StateConfigSig {
167+ class FlowState = TaintState ;
152168
153- override predicate isSource ( DataFlow:: Node source , DataFlow :: FlowState state ) {
169+ predicate isSource ( DataFlow:: Node source , FlowState state ) {
154170 source instanceof DataFlow:: ParameterNode and
155171 source .getEnclosingCallable ( ) instanceof DataFlowTargetApi and
156172 state .( TaintRead ) .getStep ( ) = 0
157173 }
158174
159- override predicate isSink ( DataFlow:: Node sink , DataFlow :: FlowState state ) {
175+ predicate isSink ( DataFlow:: Node sink , FlowState state ) {
160176 sink instanceof DataFlowImplCommon:: ReturnNodeExt and
161177 not isOwnInstanceAccessNode ( sink ) and
162178 not exists ( captureQualifierFlow ( sink .asExpr ( ) .getEnclosingCallable ( ) ) ) and
163179 ( state instanceof TaintRead or state instanceof TaintStore )
164180 }
165181
166- override predicate isAdditionalTaintStep (
167- DataFlow:: Node node1 , DataFlow:: FlowState state1 , DataFlow:: Node node2 ,
168- DataFlow:: FlowState state2
182+ predicate isAdditionalFlowStep (
183+ DataFlow:: Node node1 , FlowState state1 , DataFlow:: Node node2 , FlowState state2
169184 ) {
170185 exists ( DataFlowImplCommon:: TypedContent tc |
171186 DataFlowImplCommon:: store ( node1 , tc , node2 , _) and
@@ -184,24 +199,28 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
184199 )
185200 }
186201
187- override predicate isSanitizer ( DataFlow:: Node n ) {
202+ predicate isBarrier ( DataFlow:: Node n ) {
188203 exists ( Type t | t = n .getType ( ) and not isRelevantType ( t ) )
189204 }
190205
191- override DataFlow:: FlowFeature getAFeature ( ) {
206+ predicate isBarrier ( DataFlow:: Node node , FlowState state ) { none ( ) }
207+
208+ DataFlow:: FlowFeature getAFeature ( ) {
192209 result instanceof DataFlow:: FeatureEqualSourceSinkCallContext
193210 }
194211}
195212
213+ private module ThroughFlow = TaintTracking:: MakeWithState< ThroughFlowConfig > ;
214+
196215/**
197216 * Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
198217 */
199218string captureThroughFlow ( DataFlowTargetApi api ) {
200219 exists (
201- ThroughFlowConfig config , DataFlow:: ParameterNode p ,
202- DataFlowImplCommon :: ReturnNodeExt returnNodeExt , string input , string output
220+ DataFlow:: ParameterNode p , DataFlowImplCommon :: ReturnNodeExt returnNodeExt , string input ,
221+ string output
203222 |
204- config . hasFlow ( p , returnNodeExt ) and
223+ ThroughFlow :: hasFlow ( p , returnNodeExt ) and
205224 returnNodeExt .getEnclosingCallable ( ) = api and
206225 input = parameterNodeAsInput ( p ) and
207226 output = returnNodeAsOutput ( returnNodeExt ) and
@@ -211,41 +230,37 @@ string captureThroughFlow(DataFlowTargetApi api) {
211230}
212231
213232/**
214- * A TaintTracking Configuration used for tracking flow through APIs .
233+ * A dataflow configuration used for finding new sources .
215234 * The sources are the already known existing sources and the sinks are the API return nodes.
216235 *
217236 * This can be used to generate Source summaries for an API, if the API expose an already known source
218237 * via its return (then the API itself becomes a source).
219238 */
220- private class FromSourceConfiguration extends TaintTracking:: Configuration {
221- FromSourceConfiguration ( ) {
222- this = "FromSourceConfiguration" and any ( ActiveConfiguration ac ) .activateFromSourceConfig ( )
223- }
239+ module FromSourceConfig implements DataFlow:: ConfigSig {
240+ predicate isSource ( DataFlow:: Node source ) { ExternalFlow:: sourceNode ( source , _) }
224241
225- override predicate isSource ( DataFlow:: Node source ) { ExternalFlow:: sourceNode ( source , _) }
226-
227- override predicate isSink ( DataFlow:: Node sink ) {
242+ predicate isSink ( DataFlow:: Node sink ) {
228243 exists ( DataFlowTargetApi c |
229244 sink instanceof DataFlowImplCommon:: ReturnNodeExt and
230245 sink .getEnclosingCallable ( ) = c
231246 )
232247 }
233248
234- override DataFlow:: FlowFeature getAFeature ( ) {
235- result instanceof DataFlow:: FeatureHasSinkCallContext
236- }
249+ DataFlow:: FlowFeature getAFeature ( ) { result instanceof DataFlow:: FeatureHasSinkCallContext }
237250
238- override predicate isAdditionalTaintStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
251+ predicate isAdditionalFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
239252 isRelevantTaintStep ( node1 , node2 )
240253 }
241254}
242255
256+ private module FromSource = TaintTracking:: Make< FromSourceConfig > ;
257+
243258/**
244259 * Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`.
245260 */
246261string captureSource ( DataFlowTargetApi api ) {
247- exists ( DataFlow:: Node source , DataFlow:: Node sink , FromSourceConfiguration config , string kind |
248- config . hasFlow ( source , sink ) and
262+ exists ( DataFlow:: Node source , DataFlow:: Node sink , string kind |
263+ FromSource :: hasFlow ( source , sink ) and
249264 ExternalFlow:: sourceNode ( source , kind ) and
250265 api = sink .getEnclosingCallable ( ) and
251266 isRelevantSourceKind ( kind ) and
@@ -254,35 +269,30 @@ string captureSource(DataFlowTargetApi api) {
254269}
255270
256271/**
257- * A TaintTracking Configuration used for tracking flow through APIs .
272+ * A dataflow configuration used for finding new sinks .
258273 * The sources are the parameters of the API and the fields of the enclosing type.
259274 *
260275 * This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
261276 * into an existing known sink (then the API itself becomes a sink).
262277 */
263- private class PropagateToSinkConfiguration extends TaintTracking:: Configuration {
264- PropagateToSinkConfiguration ( ) {
265- this = "parameters or fields flowing into sinks" and
266- any ( ActiveConfiguration ac ) .activateToSinkConfig ( )
267- }
278+ module PropagateToSinkConfig implements DataFlow:: ConfigSig {
279+ predicate isSource ( DataFlow:: Node source ) { apiSource ( source ) }
268280
269- override predicate isSource ( DataFlow:: Node source ) { apiSource ( source ) }
281+ predicate isSink ( DataFlow:: Node sink ) { ExternalFlow :: sinkNode ( sink , _ ) }
270282
271- override predicate isSink ( DataFlow:: Node sink ) { ExternalFlow :: sinkNode ( sink , _ ) }
283+ predicate isBarrier ( DataFlow:: Node node ) { sinkModelSanitizer ( node ) }
272284
273- override predicate isSanitizer ( DataFlow:: Node node ) { sinkModelSanitizer ( node ) }
274-
275- override DataFlow:: FlowFeature getAFeature ( ) {
276- result instanceof DataFlow:: FeatureHasSourceCallContext
277- }
285+ DataFlow:: FlowFeature getAFeature ( ) { result instanceof DataFlow:: FeatureHasSourceCallContext }
278286}
279287
288+ private module PropagateToSink = TaintTracking:: Make< PropagateToSinkConfig > ;
289+
280290/**
281291 * Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink.
282292 */
283293string captureSink ( DataFlowTargetApi api ) {
284- exists ( DataFlow:: Node src , DataFlow:: Node sink , PropagateToSinkConfiguration config , string kind |
285- config . hasFlow ( src , sink ) and
294+ exists ( DataFlow:: Node src , DataFlow:: Node sink , string kind |
295+ PropagateToSink :: hasFlow ( src , sink ) and
286296 ExternalFlow:: sinkNode ( sink , kind ) and
287297 api = src .getEnclosingCallable ( ) and
288298 isRelevantSinkKind ( kind ) and
0 commit comments