@@ -16,6 +16,54 @@ private import semmle.python.regex
1616 * See https://www.tornadoweb.org/en/stable/.
1717 */
1818private module Tornado {
19+ /**
20+ * Provides models for the `tornado.httputil.HTTPHeaders` class
21+ *
22+ * See https://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPHeaders.
23+ */
24+ module HTTPHeaders {
25+ /**
26+ * A source of instances of `tornado.httputil.HTTPHeaders`, extend this class to model new instances.
27+ *
28+ * This can include instantiations of the class, return values from function
29+ * calls, or a special parameter that will be set when functions are called by an external
30+ * library.
31+ *
32+ * Use the predicate `HTTPHeaders::instance()` to get references to instances of `tornado.httputil.HTTPHeaders`.
33+ */
34+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
35+
36+ /** Gets a reference to an instance of `tornado.httputil.HTTPHeaders`. */
37+ private DataFlow:: TypeTrackingNode instance ( DataFlow:: TypeTracker t ) {
38+ t .start ( ) and
39+ result instanceof InstanceSource
40+ or
41+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
42+ }
43+
44+ /** Gets a reference to an instance of `tornado.httputil.HTTPHeaders`. */
45+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
46+
47+ /**
48+ * Taint propagation for `tornado.httputil.HTTPHeaders`.
49+ */
50+ private class AdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
51+ override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
52+ // Methods
53+ //
54+ // TODO: When we have tools that make it easy, model these properly to handle
55+ // `meth = obj.meth; meth()`. Until then, we'll use this more syntactic approach
56+ // (since it allows us to at least capture the most common cases).
57+ nodeFrom = instance ( ) and
58+ exists ( DataFlow:: AttrRead attr | attr .getObject ( ) = nodeFrom |
59+ // normal (non-async) methods
60+ attr .getAttributeName ( ) in [ "get_list" , "get_all" ] and
61+ nodeTo .( DataFlow:: CallCfgNode ) .getFunction ( ) = attr
62+ )
63+ }
64+ }
65+ }
66+
1967 // ---------------------------------------------------------------------------
2068 // tornado
2169 // ---------------------------------------------------------------------------
@@ -312,6 +360,13 @@ private module Tornado {
312360 )
313361 }
314362 }
363+
364+ /** An `HTTPHeaders` instance that originates from a Tornado request. */
365+ private class TornadoRequestHTTPHeadersInstances extends HTTPHeaders:: InstanceSource {
366+ TornadoRequestHTTPHeadersInstances ( ) {
367+ this .( DataFlow:: AttrRead ) .accesses ( instance ( ) , "headers" )
368+ }
369+ }
315370 }
316371 }
317372 }
0 commit comments