@@ -10,6 +10,8 @@ private import semmle.python.dataflow.new.RemoteFlowSources
10
10
private import semmle.python.Concepts
11
11
private import semmle.python.ApiGraphs
12
12
private import semmle.python.frameworks.PEP249
13
+ private import semmle.python.frameworks.internal.PoorMansFunctionResolution
14
+ private import semmle.python.frameworks.internal.SelfRefMixin
13
15
private import semmle.python.frameworks.internal.InstanceTaintStepsHelper
14
16
15
17
/** Provides models for the Python standard library. */
@@ -1316,6 +1318,161 @@ private module StdlibPrivate {
1316
1318
}
1317
1319
}
1318
1320
1321
+ // ---------------------------------------------------------------------------
1322
+ // wsgiref.simple_server
1323
+ // ---------------------------------------------------------------------------
1324
+ /** Provides models for the `wsgiref.simple_server` module. */
1325
+ private module WsgirefSimpleServer {
1326
+ class WsgiServerSubclass extends Class , SelfRefMixin {
1327
+ WsgiServerSubclass ( ) {
1328
+ this .getABase ( ) =
1329
+ API:: moduleImport ( "wsgiref" )
1330
+ .getMember ( "simple_server" )
1331
+ .getMember ( "WSGIServer" )
1332
+ .getASubclass * ( )
1333
+ .getAUse ( )
1334
+ .asExpr ( )
1335
+ }
1336
+ }
1337
+
1338
+ /**
1339
+ * A function that was passed to the `set_app` method of a
1340
+ * `wsgiref.simple_server.WSGIServer` instance.
1341
+ *
1342
+ * See https://docs.python.org/3.10/library/wsgiref.html#wsgiref.simple_server.WSGIServer.set_app
1343
+ *
1344
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L137
1345
+ * for how a request is processed and given to an application.
1346
+ */
1347
+ class WsgirefSimpleServerApplication extends HTTP:: Server:: RequestHandler:: Range {
1348
+ WsgirefSimpleServerApplication ( ) {
1349
+ exists ( DataFlow:: Node appArg , DataFlow:: CallCfgNode setAppCall |
1350
+ (
1351
+ setAppCall =
1352
+ API:: moduleImport ( "wsgiref" )
1353
+ .getMember ( "simple_server" )
1354
+ .getMember ( "WSGIServer" )
1355
+ .getASubclass * ( )
1356
+ .getReturn ( )
1357
+ .getMember ( "set_app" )
1358
+ .getACall ( )
1359
+ or
1360
+ setAppCall
1361
+ .( DataFlow:: MethodCallNode )
1362
+ .calls ( any ( WsgiServerSubclass cls ) .getASelfRef ( ) , "set_app" )
1363
+ ) and
1364
+ appArg in [ setAppCall .getArg ( 0 ) , setAppCall .getArgByName ( "application" ) ]
1365
+ |
1366
+ appArg = poorMansFunctionTracker ( this )
1367
+ )
1368
+ }
1369
+
1370
+ override Parameter getARoutedParameter ( ) { none ( ) }
1371
+
1372
+ override string getFramework ( ) { result = "Stdlib: wsgiref.simple_server application" }
1373
+ }
1374
+
1375
+ /**
1376
+ * The parameter of a `WsgirefSimpleServerApplication` that takes the WSGI environment
1377
+ * when processing a request.
1378
+ *
1379
+ * See https://docs.python.org/3.10/library/wsgiref.html#wsgiref.simple_server.WSGIRequestHandler.get_environ
1380
+ */
1381
+ class WSGIEnvirontParameter extends RemoteFlowSource:: Range , DataFlow:: ParameterNode {
1382
+ WSGIEnvirontParameter ( ) {
1383
+ exists ( WsgirefSimpleServerApplication func |
1384
+ if func .isMethod ( )
1385
+ then this .getParameter ( ) = func .getArg ( 1 )
1386
+ else this .getParameter ( ) = func .getArg ( 0 )
1387
+ )
1388
+ }
1389
+
1390
+ override string getSourceType ( ) {
1391
+ result = "Stdlib: wsgiref.simple_server application: WSGI environment parameter"
1392
+ }
1393
+ }
1394
+
1395
+ /**
1396
+ * Gets a reference to the parameter of a `WsgirefSimpleServerApplication` that
1397
+ * takes the `start_response` function.
1398
+ *
1399
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252
1400
+ */
1401
+ private DataFlow:: TypeTrackingNode startResponse ( DataFlow:: TypeTracker t ) {
1402
+ t .start ( ) and
1403
+ exists ( WsgirefSimpleServerApplication func |
1404
+ if func .isMethod ( )
1405
+ then result .( DataFlow:: ParameterNode ) .getParameter ( ) = func .getArg ( 2 )
1406
+ else result .( DataFlow:: ParameterNode ) .getParameter ( ) = func .getArg ( 1 )
1407
+ )
1408
+ or
1409
+ exists ( DataFlow:: TypeTracker t2 | result = startResponse ( t2 ) .track ( t2 , t ) )
1410
+ }
1411
+
1412
+ /**
1413
+ * Gets a reference to the parameter of a `WsgirefSimpleServerApplication` that
1414
+ * takes the `start_response` function.
1415
+ *
1416
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252
1417
+ */
1418
+ DataFlow:: Node startResponse ( ) { startResponse ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
1419
+
1420
+ /**
1421
+ * Gets a reference to the `write` function (that will write data to the response),
1422
+ * which is the return value from calling the `start_response` function.
1423
+ *
1424
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252
1425
+ */
1426
+ private DataFlow:: TypeTrackingNode writeFunction ( DataFlow:: TypeTracker t ) {
1427
+ t .start ( ) and
1428
+ result .( DataFlow:: CallCfgNode ) .getFunction ( ) = startResponse ( )
1429
+ or
1430
+ exists ( DataFlow:: TypeTracker t2 | result = writeFunction ( t2 ) .track ( t2 , t ) )
1431
+ }
1432
+
1433
+ /**
1434
+ * Gets a reference to the `write` function (that will write data to the response),
1435
+ * which is the return value from calling the `start_response` function.
1436
+ *
1437
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252
1438
+ */
1439
+ DataFlow:: Node writeFunction ( ) { writeFunction ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
1440
+
1441
+ /**
1442
+ * A call to the `write` function.
1443
+ *
1444
+ * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L276
1445
+ */
1446
+ class WsgirefSimpleServerApplicationWriteCall extends HTTP:: Server:: HttpResponse:: Range ,
1447
+ DataFlow:: CallCfgNode {
1448
+ WsgirefSimpleServerApplicationWriteCall ( ) { this .getFunction ( ) = writeFunction ( ) }
1449
+
1450
+ override DataFlow:: Node getBody ( ) { result in [ this .getArg ( 0 ) , this .getArgByName ( "data" ) ] }
1451
+
1452
+ override DataFlow:: Node getMimetypeOrContentTypeArg ( ) { none ( ) }
1453
+
1454
+ override string getMimetypeDefault ( ) { none ( ) }
1455
+ }
1456
+
1457
+ /**
1458
+ * A return from a `WsgirefSimpleServerApplication`, which is included in the response body.
1459
+ */
1460
+ class WsgirefSimpleServerApplicationReturn extends HTTP:: Server:: HttpResponse:: Range ,
1461
+ DataFlow:: CfgNode {
1462
+ WsgirefSimpleServerApplicationReturn ( ) {
1463
+ exists ( WsgirefSimpleServerApplication requestHandler |
1464
+ node = requestHandler .getAReturnValueFlowNode ( )
1465
+ )
1466
+ }
1467
+
1468
+ override DataFlow:: Node getBody ( ) { result = this }
1469
+
1470
+ override DataFlow:: Node getMimetypeOrContentTypeArg ( ) { none ( ) }
1471
+
1472
+ override string getMimetypeDefault ( ) { none ( ) }
1473
+ }
1474
+ }
1475
+
1319
1476
// ---------------------------------------------------------------------------
1320
1477
// sqlite3
1321
1478
// ---------------------------------------------------------------------------
0 commit comments