@@ -295,6 +295,66 @@ module AiohttpWebModel {
295
295
DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
296
296
}
297
297
298
+ /**
299
+ * Provides models for the `aiohttp.StreamReader` class
300
+ *
301
+ * See https://docs.aiohttp.org/en/stable/streams.html#aiohttp.StreamReader
302
+ */
303
+ module StreamReader {
304
+ /**
305
+ * A source of instances of `aiohttp.StreamReader`, extend this class to model new instances.
306
+ *
307
+ * This can include instantiations of the class, return values from function
308
+ * calls, or a special parameter that will be set when functions are called by an external
309
+ * library.
310
+ *
311
+ * Use `StreamReader::instance()` predicate to get
312
+ * references to instances of `aiohttp.StreamReader`.
313
+ */
314
+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
315
+
316
+ /** Gets a reference to an instance of `aiohttp.StreamReader`. */
317
+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
318
+ t .start ( ) and
319
+ result instanceof InstanceSource
320
+ or
321
+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
322
+ }
323
+
324
+ /** Gets a reference to an instance of `aiohttp.StreamReader`. */
325
+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
326
+
327
+ /**
328
+ * Taint propagation for `aiohttp.StreamReader`.
329
+ */
330
+ private class AiohttpStreamReaderAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
331
+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
332
+ // Methods
333
+ //
334
+ // TODO: When we have tools that make it easy, model these properly to handle
335
+ // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach
336
+ // (since it allows us to at least capture the most common cases).
337
+ nodeFrom = StreamReader:: instance ( ) and
338
+ exists ( DataFlow:: AttrRead attr | attr .getObject ( ) = nodeFrom |
339
+ // normal methods
340
+ attr .getAttributeName ( ) in [ "read_nowait" ] and
341
+ nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = attr
342
+ or
343
+ // async methods
344
+ exists ( Await await , DataFlow:: CallCfgNode call |
345
+ attr .getAttributeName ( ) in [
346
+ "read" , "readany" , "readexactly" , "readline" , "readchunk" , "iter_chunked" ,
347
+ "iter_any" , "iter_chunks"
348
+ ] and
349
+ call .getFunction ( ) = attr and
350
+ await .getValue ( ) = call .asExpr ( ) and
351
+ nodeTo .asExpr ( ) = await
352
+ )
353
+ )
354
+ }
355
+ }
356
+ }
357
+
298
358
/**
299
359
* A parameter that will receive an `aiohttp.web.Request` instance when a request
300
360
* handler is invoked.
@@ -395,6 +455,14 @@ module AiohttpWebModel {
395
455
}
396
456
}
397
457
458
+ /** An attribute read on an `aiohttp.web.Request` that is a `aiohttp.StreamReader` instance. */
459
+ class AiohttpRequestStreamReaderInstances extends StreamReader:: InstanceSource {
460
+ AiohttpRequestStreamReaderInstances ( ) {
461
+ this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
462
+ this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "content" , "_payload" ]
463
+ }
464
+ }
465
+
398
466
// ---------------------------------------------------------------------------
399
467
// aiohttp.web Response modeling
400
468
// ---------------------------------------------------------------------------
0 commit comments