@@ -2183,15 +2183,24 @@ module StdlibPrivate {
21832183 * for how a request is processed and given to an application.
21842184 */
21852185 class WsgirefSimpleServerApplication extends Http:: Server:: RequestHandler:: Range {
2186+ boolean validator ;
2187+
21862188 WsgirefSimpleServerApplication ( ) {
21872189 exists ( DataFlow:: Node appArg , DataFlow:: CallCfgNode setAppCall |
21882190 (
21892191 setAppCall =
2190- WsgirefSimpleServer:: subclassRef ( ) .getReturn ( ) .getMember ( "set_app" ) .getACall ( )
2192+ WsgirefSimpleServer:: subclassRef ( ) .getReturn ( ) .getMember ( "set_app" ) .getACall ( ) and
2193+ validator = false
21912194 or
21922195 setAppCall
21932196 .( DataFlow:: MethodCallNode )
2194- .calls ( any ( WsgiServerSubclass cls ) .getASelfRef ( ) , "set_app" )
2197+ .calls ( any ( WsgiServerSubclass cls ) .getASelfRef ( ) , "set_app" ) and
2198+ validator = false
2199+ or
2200+ // assume an application that is passed to `wsgiref.validate.validator` is eventually passed to `set_app`
2201+ setAppCall =
2202+ API:: moduleImport ( "wsgiref" ) .getMember ( "validate" ) .getMember ( "validator" ) .getACall ( ) and
2203+ validator = true
21952204 ) and
21962205 appArg in [ setAppCall .getArg ( 0 ) , setAppCall .getArgByName ( "application" ) ]
21972206 or
@@ -2201,7 +2210,8 @@ module StdlibPrivate {
22012210 .getMember ( "simple_server" )
22022211 .getMember ( "make_server" )
22032212 .getACall ( ) and
2204- appArg in [ setAppCall .getArg ( 2 ) , setAppCall .getArgByName ( "app" ) ]
2213+ appArg in [ setAppCall .getArg ( 2 ) , setAppCall .getArgByName ( "app" ) ] and
2214+ validator = false
22052215 |
22062216 appArg = poorMansFunctionTracker ( this )
22072217 )
@@ -2210,6 +2220,9 @@ module StdlibPrivate {
22102220 override Parameter getARoutedParameter ( ) { none ( ) }
22112221
22122222 override string getFramework ( ) { result = "Stdlib: wsgiref.simple_server application" }
2223+
2224+ /** Holds if this simple server application was passed to `wsgiref.validate.validator`. */
2225+ predicate isValidated ( ) { validator = true }
22132226 }
22142227
22152228 /**
@@ -2324,7 +2337,7 @@ module StdlibPrivate {
23242337 API:: Node classRef ( ) {
23252338 result = API:: moduleImport ( "wsgiref" ) .getMember ( "headers" ) .getMember ( "Headers" )
23262339 or
2327- result = ModelOutput:: getATypeNode ( "wsqiref .headers.Headers~Subclass" ) .getASubclass * ( )
2340+ result = ModelOutput:: getATypeNode ( "wsgiref .headers.Headers~Subclass" ) .getASubclass * ( )
23282341 }
23292342
23302343 /** Gets a reference to an instance of `wsgiref.headers.Headers`. */
@@ -2338,6 +2351,11 @@ module StdlibPrivate {
23382351 /** Gets a reference to an instance of `wsgiref.headers.Headers`. */
23392352 DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
23402353
2354+ /** Holds if there exists an application that is validated by `wsgiref.validate.validator`. */
2355+ private predicate existsValidatedApplication ( ) {
2356+ exists ( WsgirefSimpleServerApplication app | app .isValidated ( ) )
2357+ }
2358+
23412359 /** A class instantiation of `wsgiref.headers.Headers`, conidered as a write to a response header. */
23422360 private class WsgirefHeadersInstantiation extends Http:: Server:: ResponseHeaderBulkWrite:: Range ,
23432361 DataFlow:: CallCfgNode
@@ -2348,28 +2366,10 @@ module StdlibPrivate {
23482366 result = [ this .getArg ( 0 ) , this .getArgByName ( "headers" ) ]
23492367 }
23502368
2351- // TODO: implement validator
2352- override predicate nameAllowsNewline ( ) { any ( ) }
2353-
2354- override predicate valueAllowsNewline ( ) { any ( ) }
2355- }
2356-
2357- /**
2358- * A call to a `start_response` function that sets the response headers.
2359- */
2360- private class WsgirefSimpleServerSetHeaders extends Http:: Server:: ResponseHeaderBulkWrite:: Range ,
2361- DataFlow:: CallCfgNode
2362- {
2363- WsgirefSimpleServerSetHeaders ( ) { this .getFunction ( ) = startResponse ( ) }
2364-
2365- override DataFlow:: Node getBulkArg ( ) {
2366- result = [ this .getArg ( 1 ) , this .getArgByName ( "headers" ) ]
2367- }
2368-
2369- // TODO: implement validator
2370- override predicate nameAllowsNewline ( ) { any ( ) }
2369+ // TODO: These checks perhaps could be made more precise.
2370+ override predicate nameAllowsNewline ( ) { not existsValidatedApplication ( ) }
23712371
2372- override predicate valueAllowsNewline ( ) { any ( ) }
2372+ override predicate valueAllowsNewline ( ) { not existsValidatedApplication ( ) }
23732373 }
23742374
23752375 /** A call to a method that writes to a response header. */
@@ -2384,10 +2384,10 @@ module StdlibPrivate {
23842384
23852385 override DataFlow:: Node getValueArg ( ) { result = this .getArg ( 1 ) }
23862386
2387- // TODO: implement validator
2388- override predicate nameAllowsNewline ( ) { any ( ) }
2387+ // TODO: These checks perhaps could be made more precise.
2388+ override predicate nameAllowsNewline ( ) { not existsValidatedApplication ( ) }
23892389
2390- override predicate valueAllowsNewline ( ) { any ( ) }
2390+ override predicate valueAllowsNewline ( ) { not existsValidatedApplication ( ) }
23912391 }
23922392
23932393 /** A dict-like write to a response header. */
@@ -2410,10 +2410,28 @@ module StdlibPrivate {
24102410
24112411 override DataFlow:: Node getValueArg ( ) { result = value }
24122412
2413- // TODO: implement validator
2414- override predicate nameAllowsNewline ( ) { any ( ) }
2413+ // TODO: These checks perhaps could be made more precise.
2414+ override predicate nameAllowsNewline ( ) { not existsValidatedApplication ( ) }
2415+
2416+ override predicate valueAllowsNewline ( ) { not existsValidatedApplication ( ) }
2417+ }
2418+
2419+ /**
2420+ * A call to a `start_response` function that sets the response headers.
2421+ */
2422+ private class WsgirefSimpleServerSetHeaders extends Http:: Server:: ResponseHeaderBulkWrite:: Range ,
2423+ DataFlow:: CallCfgNode
2424+ {
2425+ WsgirefSimpleServerSetHeaders ( ) { this .getFunction ( ) = startResponse ( ) }
2426+
2427+ override DataFlow:: Node getBulkArg ( ) {
2428+ result = [ this .getArg ( 1 ) , this .getArgByName ( "headers" ) ]
2429+ }
2430+
2431+ // TODO: These checks perhaps could be made more precise.
2432+ override predicate nameAllowsNewline ( ) { not existsValidatedApplication ( ) }
24152433
2416- override predicate valueAllowsNewline ( ) { any ( ) }
2434+ override predicate valueAllowsNewline ( ) { not existsValidatedApplication ( ) }
24172435 }
24182436 }
24192437 }
0 commit comments