@@ -33,7 +33,7 @@ private module Tornado {
33
33
* WARNING: Only holds for a few predefined attributes.
34
34
*/
35
35
private DataFlow:: Node tornado_attr ( DataFlow:: TypeTracker t , string attr_name ) {
36
- attr_name in [ "web" ] and
36
+ attr_name in [ "web" , "httputil" ] and
37
37
(
38
38
t .start ( ) and
39
39
result = DataFlow:: importNode ( "tornado" + "." + attr_name )
@@ -221,6 +221,148 @@ private module Tornado {
221
221
)
222
222
}
223
223
}
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
+ }
224
366
}
225
367
}
226
368
}
0 commit comments