@@ -8,6 +8,7 @@ private import semmle.python.dataflow.new.DataFlow
88private import semmle.python.dataflow.new.RemoteFlowSources
99private import semmle.python.dataflow.new.TaintTracking
1010private import semmle.python.Concepts
11+ private import semmle.python.ApiGraphs
1112private import semmle.python.regex
1213
1314/**
@@ -19,104 +20,29 @@ private module Tornado {
1920 // tornado
2021 // ---------------------------------------------------------------------------
2122 /** Gets a reference to the `tornado` module. */
22- private DataFlow:: Node tornado ( DataFlow:: TypeTracker t ) {
23- t .start ( ) and
24- result = DataFlow:: importNode ( "tornado" )
25- or
26- exists ( DataFlow:: TypeTracker t2 | result = tornado ( t2 ) .track ( t2 , t ) )
27- }
28-
29- /** Gets a reference to the `tornado` module. */
30- DataFlow:: Node tornado ( ) { result = tornado ( DataFlow:: TypeTracker:: end ( ) ) }
31-
32- /**
33- * Gets a reference to the attribute `attr_name` of the `tornado` module.
34- * WARNING: Only holds for a few predefined attributes.
35- */
36- private DataFlow:: Node tornado_attr ( DataFlow:: TypeTracker t , string attr_name ) {
37- attr_name in [ "web" , "httputil" ] and
38- (
39- t .start ( ) and
40- result = DataFlow:: importNode ( "tornado" + "." + attr_name )
41- or
42- t .startInAttr ( attr_name ) and
43- result = tornado ( )
44- )
45- or
46- // Due to bad performance when using normal setup with `tornado_attr(t2, attr_name).track(t2, t)`
47- // we have inlined that code and forced a join
48- exists ( DataFlow:: TypeTracker t2 |
49- exists ( DataFlow:: StepSummary summary |
50- tornado_attr_first_join ( t2 , attr_name , result , summary ) and
51- t = t2 .append ( summary )
52- )
53- )
54- }
55-
56- pragma [ nomagic]
57- private predicate tornado_attr_first_join (
58- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res , DataFlow:: StepSummary summary
59- ) {
60- DataFlow:: StepSummary:: step ( tornado_attr ( t2 , attr_name ) , res , summary )
61- }
23+ API:: Node tornado ( ) { result = API:: moduleImport ( "tornado" ) }
6224
6325 /**
6426 * Gets a reference to the attribute `attr_name` of the `tornado` module.
6527 * WARNING: Only holds for a few predefined attributes.
6628 */
67- private DataFlow:: Node tornado_attr ( string attr_name ) {
68- result = tornado_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
69- }
29+ private API:: Node tornado_attr ( string attr_name ) { result = tornado ( ) .getMember ( attr_name ) }
7030
7131 /** Provides models for the `tornado` module. */
7232 module tornado {
7333 // -------------------------------------------------------------------------
7434 // tornado.web
7535 // -------------------------------------------------------------------------
7636 /** Gets a reference to the `tornado.web` module. */
77- DataFlow :: Node web ( ) { result = tornado_attr ( "web" ) }
37+ API :: Node web ( ) { result = tornado_attr ( "web" ) }
7838
7939 /** Provides models for the `tornado.web` module */
8040 module web {
8141 /**
8242 * Gets a reference to the attribute `attr_name` of the `tornado.web` module.
8343 * WARNING: Only holds for a few predefined attributes.
8444 */
85- private DataFlow:: Node web_attr ( DataFlow:: TypeTracker t , string attr_name ) {
86- attr_name in [ "RequestHandler" , "Application" ] and
87- (
88- t .start ( ) and
89- result = DataFlow:: importNode ( "tornado.web" + "." + attr_name )
90- or
91- t .startInAttr ( attr_name ) and
92- result = web ( )
93- )
94- or
95- // Due to bad performance when using normal setup with `web_attr(t2, attr_name).track(t2, t)`
96- // we have inlined that code and forced a join
97- exists ( DataFlow:: TypeTracker t2 |
98- exists ( DataFlow:: StepSummary summary |
99- web_attr_first_join ( t2 , attr_name , result , summary ) and
100- t = t2 .append ( summary )
101- )
102- )
103- }
104-
105- pragma [ nomagic]
106- private predicate web_attr_first_join (
107- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
108- DataFlow:: StepSummary summary
109- ) {
110- DataFlow:: StepSummary:: step ( web_attr ( t2 , attr_name ) , res , summary )
111- }
112-
113- /**
114- * Gets a reference to the attribute `attr_name` of the `tornado.web` module.
115- * WARNING: Only holds for a few predefined attributes.
116- */
117- private DataFlow:: Node web_attr ( string attr_name ) {
118- result = web_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
119- }
45+ private API:: Node web_attr ( string attr_name ) { result = web ( ) .getMember ( attr_name ) }
12046
12147 /**
12248 * Provides models for the `tornado.web.RequestHandler` class and subclasses.
@@ -125,22 +51,11 @@ private module Tornado {
12551 */
12652 module RequestHandler {
12753 /** Gets a reference to the `tornado.web.RequestHandler` class or any subclass. */
128- private DataFlow:: Node subclassRef ( DataFlow:: TypeTracker t ) {
129- t .start ( ) and
130- result = web_attr ( "RequestHandler" )
131- or
132- // subclasses in project code
133- result .asExpr ( ) .( ClassExpr ) .getABase ( ) = subclassRef ( t .continue ( ) ) .asExpr ( )
134- or
135- exists ( DataFlow:: TypeTracker t2 | result = subclassRef ( t2 ) .track ( t2 , t ) )
136- }
137-
138- /** Gets a reference to the `tornado.web.RequestHandler` class or any subclass. */
139- DataFlow:: Node subclassRef ( ) { result = subclassRef ( DataFlow:: TypeTracker:: end ( ) ) }
54+ API:: Node subclassRef ( ) { result = web_attr ( "RequestHandler" ) .getASubclass * ( ) }
14055
14156 /** A RequestHandler class (most likely in project code). */
14257 class RequestHandlerClass extends Class {
143- RequestHandlerClass ( ) { this .getParent ( ) = subclassRef ( ) .asExpr ( ) }
58+ RequestHandlerClass ( ) { this .getParent ( ) = subclassRef ( ) .getAUse ( ) . asExpr ( ) }
14459
14560 /** Gets a function that could handle incoming requests, if any. */
14661 Function getARequestHandler ( ) {
@@ -151,15 +66,15 @@ private module Tornado {
15166 }
15267
15368 /** Gets a reference to this class. */
154- private DataFlow:: Node getARef ( DataFlow:: TypeTracker t ) {
69+ private DataFlow:: LocalSourceNode getARef ( DataFlow:: TypeTracker t ) {
15570 t .start ( ) and
15671 result .asExpr ( ) .( ClassExpr ) = this .getParent ( )
15772 or
15873 exists ( DataFlow:: TypeTracker t2 | result = this .getARef ( t2 ) .track ( t2 , t ) )
15974 }
16075
16176 /** Gets a reference to this class. */
162- DataFlow:: Node getARef ( ) { result = this .getARef ( DataFlow:: TypeTracker:: end ( ) ) }
77+ DataFlow:: Node getARef ( ) { this .getARef ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
16378 }
16479
16580 /**
@@ -184,29 +99,31 @@ private module Tornado {
18499 }
185100
186101 /** Gets a reference to an instance of the `tornado.web.RequestHandler` class or any subclass. */
187- private DataFlow:: Node instance ( DataFlow:: TypeTracker t ) {
102+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
188103 t .start ( ) and
189104 result instanceof InstanceSource
190105 or
191106 exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
192107 }
193108
194109 /** Gets a reference to an instance of the `tornado.web.RequestHandler` class or any subclass. */
195- DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
110+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
196111
197112 /** Gets a reference to one of the methods `get_argument`, `get_body_argument`, `get_query_argument`. */
198- private DataFlow:: Node argumentMethod ( DataFlow:: TypeTracker t ) {
113+ private DataFlow:: LocalSourceNode argumentMethod ( DataFlow:: TypeTracker t ) {
199114 t .startInAttr ( [ "get_argument" , "get_body_argument" , "get_query_argument" ] ) and
200115 result = instance ( )
201116 or
202117 exists ( DataFlow:: TypeTracker t2 | result = argumentMethod ( t2 ) .track ( t2 , t ) )
203118 }
204119
205120 /** Gets a reference to one of the methods `get_argument`, `get_body_argument`, `get_query_argument`. */
206- DataFlow:: Node argumentMethod ( ) { result = argumentMethod ( DataFlow:: TypeTracker:: end ( ) ) }
121+ DataFlow:: Node argumentMethod ( ) {
122+ argumentMethod ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )
123+ }
207124
208125 /** Gets a reference to one of the methods `get_arguments`, `get_body_arguments`, `get_query_arguments`. */
209- private DataFlow:: Node argumentsMethod ( DataFlow:: TypeTracker t ) {
126+ private DataFlow:: LocalSourceNode argumentsMethod ( DataFlow:: TypeTracker t ) {
210127 t .startInAttr ( [ "get_arguments" , "get_body_arguments" , "get_query_arguments" ] ) and
211128 result = instance ( )
212129 or
@@ -217,26 +134,28 @@ private module Tornado {
217134 DataFlow:: Node argumentsMethod ( ) { result = argumentsMethod ( DataFlow:: TypeTracker:: end ( ) ) }
218135
219136 /** Gets a reference the `redirect` method. */
220- private DataFlow:: Node redirectMethod ( DataFlow:: TypeTracker t ) {
137+ private DataFlow:: LocalSourceNode redirectMethod ( DataFlow:: TypeTracker t ) {
221138 t .startInAttr ( "redirect" ) and
222139 result = instance ( )
223140 or
224141 exists ( DataFlow:: TypeTracker t2 | result = redirectMethod ( t2 ) .track ( t2 , t ) )
225142 }
226143
227144 /** Gets a reference the `redirect` method. */
228- DataFlow:: Node redirectMethod ( ) { result = redirectMethod ( DataFlow:: TypeTracker:: end ( ) ) }
145+ DataFlow:: Node redirectMethod ( ) {
146+ redirectMethod ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )
147+ }
229148
230149 /** Gets a reference to the `write` method. */
231- private DataFlow:: Node writeMethod ( DataFlow:: TypeTracker t ) {
150+ private DataFlow:: LocalSourceNode writeMethod ( DataFlow:: TypeTracker t ) {
232151 t .startInAttr ( "write" ) and
233152 result = instance ( )
234153 or
235154 exists ( DataFlow:: TypeTracker t2 | result = writeMethod ( t2 ) .track ( t2 , t ) )
236155 }
237156
238157 /** Gets a reference to the `write` method. */
239- DataFlow:: Node writeMethod ( ) { result = writeMethod ( DataFlow:: TypeTracker:: end ( ) ) }
158+ DataFlow:: Node writeMethod ( ) { writeMethod ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
240159
241160 private class AdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
242161 override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
@@ -279,15 +198,7 @@ private module Tornado {
279198 */
280199 module Application {
281200 /** Gets a reference to the `tornado.web.Application` class. */
282- private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
283- t .start ( ) and
284- result = web_attr ( "Application" )
285- or
286- exists ( DataFlow:: TypeTracker t2 | result = classRef ( t2 ) .track ( t2 , t ) )
287- }
288-
289- /** Gets a reference to the `tornado.web.Application` class. */
290- DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
201+ API:: Node classRef ( ) { result = web_attr ( "Application" ) }
291202
292203 /**
293204 * A source of instances of `tornado.web.Application`, extend this class to model new instances.
@@ -304,80 +215,46 @@ private module Tornado {
304215 class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
305216 override CallNode node ;
306217
307- ClassInstantiation ( ) { node . getFunction ( ) = classRef ( ) .asCfgNode ( ) }
218+ ClassInstantiation ( ) { this = classRef ( ) .getACall ( ) }
308219 }
309220
310221 /** Gets a reference to an instance of `tornado.web.Application`. */
311- private DataFlow:: Node instance ( DataFlow:: TypeTracker t ) {
222+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
312223 t .start ( ) and
313224 result instanceof InstanceSource
314225 or
315226 exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
316227 }
317228
318229 /** Gets a reference to an instance of `tornado.web.Application`. */
319- DataFlow:: Node instance ( ) { result = instance ( DataFlow:: TypeTracker:: end ( ) ) }
230+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
320231
321232 /** Gets a reference to the `add_handlers` method. */
322- private DataFlow:: Node add_handlers ( DataFlow:: TypeTracker t ) {
233+ private DataFlow:: LocalSourceNode add_handlers ( DataFlow:: TypeTracker t ) {
323234 t .startInAttr ( "add_handlers" ) and
324235 result = instance ( )
325236 or
326237 exists ( DataFlow:: TypeTracker t2 | result = add_handlers ( t2 ) .track ( t2 , t ) )
327238 }
328239
329240 /** Gets a reference to the `add_handlers` method. */
330- DataFlow:: Node add_handlers ( ) { result = add_handlers ( DataFlow:: TypeTracker:: end ( ) ) }
241+ DataFlow:: Node add_handlers ( ) { add_handlers ( DataFlow:: TypeTracker:: end ( ) ) . flowsTo ( result ) }
331242 }
332243 }
333244
334245 // -------------------------------------------------------------------------
335246 // tornado.httputil
336247 // -------------------------------------------------------------------------
337248 /** Gets a reference to the `tornado.httputil` module. */
338- DataFlow :: Node httputil ( ) { result = tornado_attr ( "httputil" ) }
249+ API :: Node httputil ( ) { result = tornado_attr ( "httputil" ) }
339250
340251 /** Provides models for the `tornado.httputil` module */
341252 module httputil {
342253 /**
343254 * Gets a reference to the attribute `attr_name` of the `tornado.httputil` module.
344255 * WARNING: Only holds for a few predefined attributes.
345256 */
346- private DataFlow:: Node httputil_attr ( DataFlow:: TypeTracker t , string attr_name ) {
347- attr_name in [ "HTTPServerRequest" ] and
348- (
349- t .start ( ) and
350- result = DataFlow:: importNode ( "tornado.httputil" + "." + attr_name )
351- or
352- t .startInAttr ( attr_name ) and
353- result = httputil ( )
354- )
355- or
356- // Due to bad performance when using normal setup with `httputil_attr(t2, attr_name).track(t2, t)`
357- // we have inlined that code and forced a join
358- exists ( DataFlow:: TypeTracker t2 |
359- exists ( DataFlow:: StepSummary summary |
360- httputil_attr_first_join ( t2 , attr_name , result , summary ) and
361- t = t2 .append ( summary )
362- )
363- )
364- }
365-
366- pragma [ nomagic]
367- private predicate httputil_attr_first_join (
368- DataFlow:: TypeTracker t2 , string attr_name , DataFlow:: Node res ,
369- DataFlow:: StepSummary summary
370- ) {
371- DataFlow:: StepSummary:: step ( httputil_attr ( t2 , attr_name ) , res , summary )
372- }
373-
374- /**
375- * Gets a reference to the attribute `attr_name` of the `tornado.httputil` module.
376- * WARNING: Only holds for a few predefined attributes.
377- */
378- private DataFlow:: Node httputil_attr ( string attr_name ) {
379- result = httputil_attr ( DataFlow:: TypeTracker:: end ( ) , attr_name )
380- }
257+ private API:: Node httputil_attr ( string attr_name ) { result = httputil ( ) .getMember ( attr_name ) }
381258
382259 /**
383260 * Provides models for the `tornado.httputil.HttpServerRequest` class
@@ -386,15 +263,7 @@ private module Tornado {
386263 */
387264 module HttpServerRequest {
388265 /** Gets a reference to the `tornado.httputil.HttpServerRequest` class. */
389- private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
390- t .start ( ) and
391- result = httputil_attr ( "HttpServerRequest" )
392- or
393- exists ( DataFlow:: TypeTracker t2 | result = classRef ( t2 ) .track ( t2 , t ) )
394- }
395-
396- /** Gets a reference to the `tornado.httputil.HttpServerRequest` class. */
397- DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
266+ API:: Node classRef ( ) { result = httputil_attr ( "HttpServerRequest" ) }
398267
399268 /**
400269 * A source of instances of `tornado.httputil.HttpServerRequest`, extend this class to model new instances.
@@ -411,7 +280,7 @@ private module Tornado {
411280 private class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
412281 override CallNode node ;
413282
414- ClassInstantiation ( ) { node . getFunction ( ) = classRef ( ) .asCfgNode ( ) }
283+ ClassInstantiation ( ) { this = classRef ( ) .getACall ( ) }
415284 }
416285
417286 /** Gets a reference to an instance of `tornado.httputil.HttpServerRequest`. */
0 commit comments