@@ -10,6 +10,8 @@ private import semmle.python.dataflow.new.RemoteFlowSources
1010private  import  semmle.python.Concepts
1111private  import  semmle.python.ApiGraphs
1212private  import  semmle.python.frameworks.PEP249
13+ private  import  semmle.python.frameworks.internal.PoorMansFunctionResolution
14+ private  import  semmle.python.frameworks.internal.SelfRefMixin
1315private  import  semmle.python.frameworks.internal.InstanceTaintStepsHelper
1416
1517/** Provides models for the Python standard library. */ 
@@ -1349,6 +1351,161 @@ private module StdlibPrivate {
13491351    } 
13501352  } 
13511353
1354+   // --------------------------------------------------------------------------- 
1355+   // wsgiref.simple_server 
1356+   // --------------------------------------------------------------------------- 
1357+   /** Provides models for the `wsgiref.simple_server` module. */ 
1358+   private  module  WsgirefSimpleServer { 
1359+     class  WsgiServerSubclass  extends  Class ,  SelfRefMixin  { 
1360+       WsgiServerSubclass ( )  { 
1361+         this .getABase ( )  = 
1362+           API:: moduleImport ( "wsgiref" ) 
1363+               .getMember ( "simple_server" ) 
1364+               .getMember ( "WSGIServer" ) 
1365+               .getASubclass * ( ) 
1366+               .getAUse ( ) 
1367+               .asExpr ( ) 
1368+       } 
1369+     } 
1370+ 
1371+     /** 
1372+      * A function that was passed to the `set_app` method of a 
1373+      * `wsgiref.simple_server.WSGIServer` instance. 
1374+      * 
1375+      * See https://docs.python.org/3.10/library/wsgiref.html#wsgiref.simple_server.WSGIServer.set_app 
1376+      * 
1377+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L137 
1378+      * for how a request is processed and given to an application. 
1379+      */ 
1380+     class  WsgirefSimpleServerApplication  extends  HTTP:: Server:: RequestHandler:: Range  { 
1381+       WsgirefSimpleServerApplication ( )  { 
1382+         exists ( DataFlow:: Node  appArg ,  DataFlow:: CallCfgNode  setAppCall  | 
1383+           ( 
1384+             setAppCall  = 
1385+               API:: moduleImport ( "wsgiref" ) 
1386+                   .getMember ( "simple_server" ) 
1387+                   .getMember ( "WSGIServer" ) 
1388+                   .getASubclass * ( ) 
1389+                   .getReturn ( ) 
1390+                   .getMember ( "set_app" ) 
1391+                   .getACall ( ) 
1392+             or 
1393+             setAppCall 
1394+                 .( DataFlow:: MethodCallNode ) 
1395+                 .calls ( any ( WsgiServerSubclass  cls ) .getASelfRef ( ) ,  "set_app" ) 
1396+           )  and 
1397+           appArg  in  [ setAppCall .getArg ( 0 ) ,  setAppCall .getArgByName ( "application" ) ] 
1398+         | 
1399+           appArg  =  poorMansFunctionTracker ( this ) 
1400+         ) 
1401+       } 
1402+ 
1403+       override  Parameter  getARoutedParameter ( )  {  none ( )  } 
1404+ 
1405+       override  string  getFramework ( )  {  result  =  "Stdlib: wsgiref.simple_server application"  } 
1406+     } 
1407+ 
1408+     /** 
1409+      * The parameter of a `WsgirefSimpleServerApplication` that takes the WSGI environment 
1410+      * when processing a request. 
1411+      * 
1412+      * See https://docs.python.org/3.10/library/wsgiref.html#wsgiref.simple_server.WSGIRequestHandler.get_environ 
1413+      */ 
1414+     class  WSGIEnvirontParameter  extends  RemoteFlowSource:: Range ,  DataFlow:: ParameterNode  { 
1415+       WSGIEnvirontParameter ( )  { 
1416+         exists ( WsgirefSimpleServerApplication  func  | 
1417+           if  func .isMethod ( ) 
1418+           then  this .getParameter ( )  =  func .getArg ( 1 ) 
1419+           else  this .getParameter ( )  =  func .getArg ( 0 ) 
1420+         ) 
1421+       } 
1422+ 
1423+       override  string  getSourceType ( )  { 
1424+         result  =  "Stdlib: wsgiref.simple_server application: WSGI environment parameter" 
1425+       } 
1426+     } 
1427+ 
1428+     /** 
1429+      * Gets a reference to the parameter of a `WsgirefSimpleServerApplication` that 
1430+      * takes the `start_response` function. 
1431+      * 
1432+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252 
1433+      */ 
1434+     private  DataFlow:: TypeTrackingNode  startResponse ( DataFlow:: TypeTracker  t )  { 
1435+       t .start ( )  and 
1436+       exists ( WsgirefSimpleServerApplication  func  | 
1437+         if  func .isMethod ( ) 
1438+         then  result .( DataFlow:: ParameterNode ) .getParameter ( )  =  func .getArg ( 2 ) 
1439+         else  result .( DataFlow:: ParameterNode ) .getParameter ( )  =  func .getArg ( 1 ) 
1440+       ) 
1441+       or 
1442+       exists ( DataFlow:: TypeTracker  t2  |  result  =  startResponse ( t2 ) .track ( t2 ,  t ) ) 
1443+     } 
1444+ 
1445+     /** 
1446+      * Gets a reference to the parameter of a `WsgirefSimpleServerApplication` that 
1447+      * takes the `start_response` function. 
1448+      * 
1449+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252 
1450+      */ 
1451+     DataFlow:: Node  startResponse ( )  {  startResponse ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )  } 
1452+ 
1453+     /** 
1454+      * Gets a reference to the `write` function (that will write data to the response), 
1455+      * which is the return value from calling the `start_response` function. 
1456+      * 
1457+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252 
1458+      */ 
1459+     private  DataFlow:: TypeTrackingNode  writeFunction ( DataFlow:: TypeTracker  t )  { 
1460+       t .start ( )  and 
1461+       result .( DataFlow:: CallCfgNode ) .getFunction ( )  =  startResponse ( ) 
1462+       or 
1463+       exists ( DataFlow:: TypeTracker  t2  |  result  =  writeFunction ( t2 ) .track ( t2 ,  t ) ) 
1464+     } 
1465+ 
1466+     /** 
1467+      * Gets a reference to the `write` function (that will write data to the response), 
1468+      * which is the return value from calling the `start_response` function. 
1469+      * 
1470+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L225-L252 
1471+      */ 
1472+     DataFlow:: Node  writeFunction ( )  {  writeFunction ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )  } 
1473+ 
1474+     /** 
1475+      * A call to the `write` function. 
1476+      * 
1477+      * See https://github.com/python/cpython/blob/b567b9d74bd9e476a3027335873bb0508d6e450f/Lib/wsgiref/handlers.py#L276 
1478+      */ 
1479+     class  WsgirefSimpleServerApplicationWriteCall  extends  HTTP:: Server:: HttpResponse:: Range , 
1480+       DataFlow:: CallCfgNode  { 
1481+       WsgirefSimpleServerApplicationWriteCall ( )  {  this .getFunction ( )  =  writeFunction ( )  } 
1482+ 
1483+       override  DataFlow:: Node  getBody ( )  {  result  in  [ this .getArg ( 0 ) ,  this .getArgByName ( "data" ) ]  } 
1484+ 
1485+       override  DataFlow:: Node  getMimetypeOrContentTypeArg ( )  {  none ( )  } 
1486+ 
1487+       override  string  getMimetypeDefault ( )  {  none ( )  } 
1488+     } 
1489+ 
1490+     /** 
1491+      * A return from a `WsgirefSimpleServerApplication`, which is included in the response body. 
1492+      */ 
1493+     class  WsgirefSimpleServerApplicationReturn  extends  HTTP:: Server:: HttpResponse:: Range , 
1494+       DataFlow:: CfgNode  { 
1495+       WsgirefSimpleServerApplicationReturn ( )  { 
1496+         exists ( WsgirefSimpleServerApplication  requestHandler  | 
1497+           node  =  requestHandler .getAReturnValueFlowNode ( ) 
1498+         ) 
1499+       } 
1500+ 
1501+       override  DataFlow:: Node  getBody ( )  {  result  =  this  } 
1502+ 
1503+       override  DataFlow:: Node  getMimetypeOrContentTypeArg ( )  {  none ( )  } 
1504+ 
1505+       override  string  getMimetypeDefault ( )  {  none ( )  } 
1506+     } 
1507+   } 
1508+ 
13521509  // --------------------------------------------------------------------------- 
13531510  // sqlite3 
13541511  // --------------------------------------------------------------------------- 
0 commit comments