@@ -33,7 +33,7 @@ private module Tornado {
3333 * WARNING: Only holds for a few predefined attributes.
3434 */
3535 private DataFlow:: Node tornado_attr ( DataFlow:: TypeTracker t , string attr_name ) {
36- attr_name in [ "web" ] and
36+ attr_name in [ "web" , "httputil" ] and
3737 (
3838 t .start ( ) and
3939 result = DataFlow:: importNode ( "tornado" + "." + attr_name )
@@ -221,6 +221,148 @@ private module Tornado {
221221 )
222222 }
223223 }
224+
225+ private class RequestAttrAccess extends tornado:: httputil:: HttpServerRequest:: InstanceSource {
226+ RequestAttrAccess ( ) {
227+ this .( DataFlow:: AttrRead ) .getObject ( ) = instance ( ) and
228+ this .( DataFlow:: AttrRead ) .getAttributeName ( ) = "request"
229+ }
230+ }
231+ }
232+ }
233+
234+ // -------------------------------------------------------------------------
235+ // tornado.httputil
236+ // -------------------------------------------------------------------------
237+ /** Gets a reference to the `tornado.httputil` module. */
238+ DataFlow:: Node httputil ( ) { result = tornado_attr ( "httputil" ) }
239+
240+ /** Provides models for the `tornado.httputil` module */
241+ module httputil {
242+ /**
243+ * Gets a reference to the attribute `attr_name` of the `tornado.httputil` module.
244+ * WARNING: Only holds for a few predefined attributes.
245+ */
246+ private DataFlow:: Node httputil_attr ( DataFlow:: TypeTracker t , string attr_name ) {
247+ attr_name in [ "HTTPServerRequest" ] and
248+ (
249+ t .start ( ) and
250+ result = DataFlow:: importNode ( "tornado.httputil" + "." + attr_name )
251+ or
252+ t .startInAttr ( attr_name ) and
253+ result = httputil ( )
254+ )
255+ or
256+ // Due to bad performance when using normal setup with `httputil_attr(t2, attr_name).track(t2, t)`
257+ // we have inlined that code and forced a join
258+ exists ( DataFlow:: TypeTracker t2 |
259+ exists ( DataFlow:: StepSummary summary |
260+ httputil_attr_first_join ( t2 , attr_name , result , summary ) and
261+ t = t2 .append ( summary )
262+ )
263+ )
264+ }
265+
266+ pragma [ nomagic]
267+ private predicate httputil_attr_first_join (
268+ DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
269+ DataFlow:: StepSummary summary
270+ ) {
271+ DataFlow:: StepSummary:: step ( httputil_attr ( t2 , attr_name ) , res , summary )
272+ }
273+
274+ /**
275+ * Gets a reference to the attribute `attr_name` of the `tornado.httputil` module.
276+ * WARNING: Only holds for a few predefined attributes.
277+ */
278+ private DataFlow:: Node httputil_attr ( string attr_name ) {
279+ result = httputil_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
280+ }
281+
282+ /**
283+ * Provides models for the `tornado.httputil.HttpServerRequest` class
284+ *
285+ * See https://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPServerRequest.
286+ */
287+ module HttpServerRequest {
288+ /** Gets a reference to the `tornado.httputil.HttpServerRequest` class. */
289+ private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
290+ t .start ( ) and
291+ result = httputil_attr ( "HttpServerRequest" )
292+ or
293+ exists ( DataFlow:: TypeTracker t2 | result = classRef ( t2 ) .track ( t2 , t ) )
294+ }
295+
296+ /** Gets a reference to the `tornado.httputil.HttpServerRequest` class. */
297+ DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
298+
299+ /**
300+ * A source of instances of `tornado.httputil.HttpServerRequest`, extend this class to model new instances.
301+ *
302+ * This can include instantiations of the class, return values from function
303+ * calls, or a special parameter that will be set when functions are called by an external
304+ * library.
305+ *
306+ * Use the predicate `HttpServerRequest::instance()` to get references to instances of `tornado.httputil.HttpServerRequest`.
307+ */
308+ abstract class InstanceSource extends DataFlow:: Node { }
309+
310+ /** A direct instantiation of `tornado.httputil.HttpServerRequest`. */
311+ private class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
312+ override CallNode node ;
313+
314+ ClassInstantiation ( ) { node .getFunction ( ) = classRef ( ) .asCfgNode ( ) }
315+ }
316+
317+ /** Gets a reference to an instance of `tornado.httputil.HttpServerRequest`. */
318+ private DataFlow:: Node instance ( DataFlow:: TypeTracker t ) {
319+ t .start ( ) and
320+ result instanceof InstanceSource
321+ or
322+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
323+ }
324+
325+ /** Gets a reference to an instance of `tornado.httputil.HttpServerRequest`. */
326+ DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
327+
328+ /** Gets a reference to the `full_url` method. */
329+ private DataFlow:: Node full_url ( DataFlow:: TypeTracker t ) {
330+ t .startInAttr ( "full_url" ) and
331+ result = instance ( )
332+ or
333+ exists ( DataFlow:: TypeTracker t2 | result = full_url ( t2 ) .track ( t2 , t ) )
334+ }
335+
336+ /** Gets a reference to the `full_url` method. */
337+ DataFlow:: Node full_url ( ) { result = full_url ( DataFlow:: TypeTracker:: end ( ) ) }
338+
339+ private class AdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
340+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
341+ // Method access
342+ nodeTo .( DataFlow:: AttrRead ) .getObject ( ) = nodeFrom and
343+ nodeFrom = instance ( ) and
344+ nodeTo in [ full_url ( ) ]
345+ or
346+ // Method call
347+ nodeTo .asCfgNode ( ) .( CallNode ) .getFunction ( ) = nodeFrom .asCfgNode ( ) and
348+ nodeFrom in [ full_url ( ) ]
349+ or
350+ // Attributes
351+ nodeFrom = instance ( ) and
352+ exists ( DataFlow:: AttrRead read | nodeTo = read and read .getObject ( ) = nodeFrom |
353+ read .getAttributeName ( ) in [
354+ // str / bytes
355+ "uri" , "path" , "query" , "remote_ip" , "body" ,
356+ // Dict[str, List[bytes]]
357+ "arguments" , "query_arguments" , "body_arguments" ,
358+ // dict-like, https://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPHeaders
359+ "headers" ,
360+ // Dict[str, http.cookies.Morsel]
361+ "cookies"
362+ ]
363+ )
364+ }
365+ }
224366 }
225367 }
226368 }
0 commit comments