@@ -13,6 +13,7 @@ private import semmle.python.frameworks.internal.PoorMansFunctionResolution
13
13
private import semmle.python.frameworks.internal.SelfRefMixin
14
14
private import semmle.python.frameworks.Multidict
15
15
private import semmle.python.frameworks.Yarl
16
+ private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
16
17
17
18
/**
18
19
* INTERNAL: Do not use.
@@ -293,6 +294,65 @@ module AiohttpWebModel {
293
294
294
295
/** Gets a reference to an instance of `aiohttp.web.Request`. */
295
296
DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
297
+
298
+ /**
299
+ * Taint propagation for `aiohttp.web.Request`.
300
+ */
301
+ private class InstanceTaintSteps extends InstanceTaintStepsHelper {
302
+ InstanceTaintSteps ( ) { this = "aiohttp.web.Request" }
303
+
304
+ override DataFlow:: Node getInstance ( ) { result = instance ( ) }
305
+
306
+ override string getAttributeName ( ) {
307
+ result in [
308
+ "url" , "rel_url" , "forwarded" , "host" , "remote" , "path" , "path_qs" , "raw_path" , "query" ,
309
+ "headers" , "transport" , "cookies" , "content" , "_payload" , "content_type" , "charset" ,
310
+ "http_range" , "if_modified_since" , "if_unmodified_since" , "if_range" , "match_info"
311
+ ]
312
+ }
313
+
314
+ override string getMethodName ( ) { result in [ "clone" , "get_extra_info" ] }
315
+
316
+ override string getAsyncMethodName ( ) {
317
+ result in [ "read" , "text" , "json" , "multipart" , "post" ]
318
+ }
319
+ }
320
+
321
+ /** An attribute read on an `aiohttp.web.Request` that is a `MultiDictProxy` instance. */
322
+ class AiohttpRequestMultiDictProxyInstances extends Multidict:: MultiDictProxy:: InstanceSource {
323
+ AiohttpRequestMultiDictProxyInstances ( ) {
324
+ this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
325
+ this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "query" , "headers" ]
326
+ or
327
+ // Handle the common case of `x = await request.post()`
328
+ // but don't try to handle anything else, since we don't have an easy way to do this yet.
329
+ // TODO: more complete handling of `await request.post()`
330
+ exists ( Await await , DataFlow:: CallCfgNode call , DataFlow:: AttrRead read |
331
+ this .asExpr ( ) = await
332
+ |
333
+ read .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
334
+ read .( DataFlow:: AttrRead ) .getAttributeName ( ) = "post" and
335
+ call .getFunction ( ) = read and
336
+ await .getValue ( ) = call .asExpr ( )
337
+ )
338
+ }
339
+ }
340
+
341
+ /** An attribute read on an `aiohttp.web.Request` that is a `yarl.URL` instance. */
342
+ class AiohttpRequestYarlUrlInstances extends Yarl:: Url:: InstanceSource {
343
+ AiohttpRequestYarlUrlInstances ( ) {
344
+ this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
345
+ this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "url" , "rel_url" ]
346
+ }
347
+ }
348
+
349
+ /** An attribute read on an `aiohttp.web.Request` that is a `aiohttp.StreamReader` instance. */
350
+ class AiohttpRequestStreamReaderInstances extends StreamReader:: InstanceSource {
351
+ AiohttpRequestStreamReaderInstances ( ) {
352
+ this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
353
+ this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "content" , "_payload" ]
354
+ }
355
+ }
296
356
}
297
357
298
358
/**
@@ -357,30 +417,20 @@ module AiohttpWebModel {
357
417
/**
358
418
* Taint propagation for `aiohttp.StreamReader`.
359
419
*/
360
- private class AiohttpStreamReaderAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
361
- override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
362
- // Methods
363
- //
364
- // TODO: When we have tools that make it easy, model these properly to handle
365
- // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach
366
- // (since it allows us to at least capture the most common cases).
367
- nodeFrom = StreamReader:: instance ( ) and
368
- exists ( DataFlow:: AttrRead attr | attr .getObject ( ) = nodeFrom |
369
- // normal methods
370
- attr .getAttributeName ( ) in [ "read_nowait" ] and
371
- nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = attr
372
- or
373
- // async methods
374
- exists ( Await await , DataFlow:: CallCfgNode call |
375
- attr .getAttributeName ( ) in [
376
- "read" , "readany" , "readexactly" , "readline" , "readchunk" , "iter_chunked" ,
377
- "iter_any" , "iter_chunks"
378
- ] and
379
- call .getFunction ( ) = attr and
380
- await .getValue ( ) = call .asExpr ( ) and
381
- nodeTo .asExpr ( ) = await
382
- )
383
- )
420
+ private class InstanceTaintSteps extends InstanceTaintStepsHelper {
421
+ InstanceTaintSteps ( ) { this = "aiohttp.StreamReader" }
422
+
423
+ override DataFlow:: Node getInstance ( ) { result = instance ( ) }
424
+
425
+ override string getAttributeName ( ) { none ( ) }
426
+
427
+ override string getMethodName ( ) { result in [ "read_nowait" ] }
428
+
429
+ override string getAsyncMethodName ( ) {
430
+ result in [
431
+ "read" , "readany" , "readexactly" , "readline" , "readchunk" , "iter_chunked" , "iter_any" ,
432
+ "iter_chunks"
433
+ ]
384
434
}
385
435
}
386
436
}
@@ -431,80 +481,6 @@ module AiohttpWebModel {
431
481
}
432
482
}
433
483
434
- /**
435
- * Taint propagation for `aiohttp.web.Request`.
436
- *
437
- * See https://docs.aiohttp.org/en/stable/web_reference.html#request-and-base-request
438
- */
439
- private class AiohttpRequestAdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
440
- override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
441
- // Methods
442
- //
443
- // TODO: When we have tools that make it easy, model these properly to handle
444
- // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach
445
- // (since it allows us to at least capture the most common cases).
446
- nodeFrom = Request:: instance ( ) and
447
- exists ( DataFlow:: AttrRead attr | attr .getObject ( ) = nodeFrom |
448
- // normal methods
449
- attr .getAttributeName ( ) in [ "clone" , "get_extra_info" ] and
450
- nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = attr
451
- or
452
- // async methods
453
- exists ( Await await , DataFlow:: CallCfgNode call |
454
- attr .getAttributeName ( ) in [ "read" , "text" , "json" , "multipart" , "post" ] and
455
- call .getFunction ( ) = attr and
456
- await .getValue ( ) = call .asExpr ( ) and
457
- nodeTo .asExpr ( ) = await
458
- )
459
- )
460
- or
461
- // Attributes
462
- nodeFrom = Request:: instance ( ) and
463
- nodeTo .( DataFlow:: AttrRead ) .getObject ( ) = nodeFrom and
464
- nodeTo .( DataFlow:: AttrRead ) .getAttributeName ( ) in [
465
- "url" , "rel_url" , "forwarded" , "host" , "remote" , "path" , "path_qs" , "raw_path" , "query" ,
466
- "headers" , "transport" , "cookies" , "content" , "_payload" , "content_type" , "charset" ,
467
- "http_range" , "if_modified_since" , "if_unmodified_since" , "if_range" , "match_info"
468
- ]
469
- }
470
- }
471
-
472
- /** An attribute read on an `aiohttp.web.Request` that is a `MultiDictProxy` instance. */
473
- class AiohttpRequestMultiDictProxyInstances extends Multidict:: MultiDictProxy:: InstanceSource {
474
- AiohttpRequestMultiDictProxyInstances ( ) {
475
- this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
476
- this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "query" , "headers" ]
477
- or
478
- // Handle the common case of `x = await request.post()`
479
- // but don't try to handle anything else, since we don't have an easy way to do this yet.
480
- // TODO: more complete handling of `await request.post()`
481
- exists ( Await await , DataFlow:: CallCfgNode call , DataFlow:: AttrRead read |
482
- this .asExpr ( ) = await
483
- |
484
- read .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
485
- read .( DataFlow:: AttrRead ) .getAttributeName ( ) = "post" and
486
- call .getFunction ( ) = read and
487
- await .getValue ( ) = call .asExpr ( )
488
- )
489
- }
490
- }
491
-
492
- /** An attribute read on an `aiohttp.web.Request` that is a `yarl.URL` instance. */
493
- class AiohttpRequestYarlUrlInstances extends Yarl:: Url:: InstanceSource {
494
- AiohttpRequestYarlUrlInstances ( ) {
495
- this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
496
- this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "url" , "rel_url" ]
497
- }
498
- }
499
-
500
- /** An attribute read on an `aiohttp.web.Request` that is a `aiohttp.StreamReader` instance. */
501
- class AiohttpRequestStreamReaderInstances extends StreamReader:: InstanceSource {
502
- AiohttpRequestStreamReaderInstances ( ) {
503
- this .( DataFlow:: AttrRead ) .getObject ( ) = Request:: instance ( ) and
504
- this .( DataFlow:: AttrRead ) .getAttributeName ( ) in [ "content" , "_payload" ]
505
- }
506
- }
507
-
508
484
// ---------------------------------------------------------------------------
509
485
// aiohttp.web Response modeling
510
486
// ---------------------------------------------------------------------------
0 commit comments