@@ -8,6 +8,7 @@ private import semmle.python.dataflow.new.DataFlow
8
8
private import semmle.python.dataflow.new.RemoteFlowSources
9
9
private import semmle.python.dataflow.new.TaintTracking
10
10
private import semmle.python.Concepts
11
+ private import semmle.python.ApiGraphs
11
12
private import semmle.python.regex
12
13
13
14
/**
@@ -19,104 +20,29 @@ private module Tornado {
19
20
// tornado
20
21
// ---------------------------------------------------------------------------
21
22
/** 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" ) }
62
24
63
25
/**
64
26
* Gets a reference to the attribute `attr_name` of the `tornado` module.
65
27
* WARNING: Only holds for a few predefined attributes.
66
28
*/
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 ) }
70
30
71
31
/** Provides models for the `tornado` module. */
72
32
module tornado {
73
33
// -------------------------------------------------------------------------
74
34
// tornado.web
75
35
// -------------------------------------------------------------------------
76
36
/** Gets a reference to the `tornado.web` module. */
77
- DataFlow :: Node web ( ) { result = tornado_attr ( "web" ) }
37
+ API :: Node web ( ) { result = tornado_attr ( "web" ) }
78
38
79
39
/** Provides models for the `tornado.web` module */
80
40
module web {
81
41
/**
82
42
* Gets a reference to the attribute `attr_name` of the `tornado.web` module.
83
43
* WARNING: Only holds for a few predefined attributes.
84
44
*/
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 ) }
120
46
121
47
/**
122
48
* Provides models for the `tornado.web.RequestHandler` class and subclasses.
@@ -125,22 +51,11 @@ private module Tornado {
125
51
*/
126
52
module RequestHandler {
127
53
/** 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 * ( ) }
140
55
141
56
/** A RequestHandler class (most likely in project code). */
142
57
class RequestHandlerClass extends Class {
143
- RequestHandlerClass ( ) { this .getParent ( ) = subclassRef ( ) .asExpr ( ) }
58
+ RequestHandlerClass ( ) { this .getParent ( ) = subclassRef ( ) .getAUse ( ) . asExpr ( ) }
144
59
145
60
/** Gets a function that could handle incoming requests, if any. */
146
61
Function getARequestHandler ( ) {
@@ -151,15 +66,15 @@ private module Tornado {
151
66
}
152
67
153
68
/** Gets a reference to this class. */
154
- private DataFlow:: Node getARef ( DataFlow:: TypeTracker t ) {
69
+ private DataFlow:: LocalSourceNode getARef ( DataFlow:: TypeTracker t ) {
155
70
t .start ( ) and
156
71
result .asExpr ( ) .( ClassExpr ) = this .getParent ( )
157
72
or
158
73
exists ( DataFlow:: TypeTracker t2 | result = this .getARef ( t2 ) .track ( t2 , t ) )
159
74
}
160
75
161
76
/** 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 ) }
163
78
}
164
79
165
80
/**
@@ -184,29 +99,31 @@ private module Tornado {
184
99
}
185
100
186
101
/** 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 ) {
188
103
t .start ( ) and
189
104
result instanceof InstanceSource
190
105
or
191
106
exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
192
107
}
193
108
194
109
/** 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 ) }
196
111
197
112
/** 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 ) {
199
114
t .startInAttr ( [ "get_argument" , "get_body_argument" , "get_query_argument" ] ) and
200
115
result = instance ( )
201
116
or
202
117
exists ( DataFlow:: TypeTracker t2 | result = argumentMethod ( t2 ) .track ( t2 , t ) )
203
118
}
204
119
205
120
/** 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
+ }
207
124
208
125
/** 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 ) {
210
127
t .startInAttr ( [ "get_arguments" , "get_body_arguments" , "get_query_arguments" ] ) and
211
128
result = instance ( )
212
129
or
@@ -217,26 +134,28 @@ private module Tornado {
217
134
DataFlow:: Node argumentsMethod ( ) { result = argumentsMethod ( DataFlow:: TypeTracker:: end ( ) ) }
218
135
219
136
/** Gets a reference the `redirect` method. */
220
- private DataFlow:: Node redirectMethod ( DataFlow:: TypeTracker t ) {
137
+ private DataFlow:: LocalSourceNode redirectMethod ( DataFlow:: TypeTracker t ) {
221
138
t .startInAttr ( "redirect" ) and
222
139
result = instance ( )
223
140
or
224
141
exists ( DataFlow:: TypeTracker t2 | result = redirectMethod ( t2 ) .track ( t2 , t ) )
225
142
}
226
143
227
144
/** 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
+ }
229
148
230
149
/** Gets a reference to the `write` method. */
231
- private DataFlow:: Node writeMethod ( DataFlow:: TypeTracker t ) {
150
+ private DataFlow:: LocalSourceNode writeMethod ( DataFlow:: TypeTracker t ) {
232
151
t .startInAttr ( "write" ) and
233
152
result = instance ( )
234
153
or
235
154
exists ( DataFlow:: TypeTracker t2 | result = writeMethod ( t2 ) .track ( t2 , t ) )
236
155
}
237
156
238
157
/** 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 ) }
240
159
241
160
private class AdditionalTaintStep extends TaintTracking:: AdditionalTaintStep {
242
161
override predicate step ( DataFlow:: Node nodeFrom , DataFlow:: Node nodeTo ) {
@@ -279,15 +198,7 @@ private module Tornado {
279
198
*/
280
199
module Application {
281
200
/** 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" ) }
291
202
292
203
/**
293
204
* A source of instances of `tornado.web.Application`, extend this class to model new instances.
@@ -304,80 +215,46 @@ private module Tornado {
304
215
class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
305
216
override CallNode node ;
306
217
307
- ClassInstantiation ( ) { node . getFunction ( ) = classRef ( ) .asCfgNode ( ) }
218
+ ClassInstantiation ( ) { this = classRef ( ) .getACall ( ) }
308
219
}
309
220
310
221
/** 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 ) {
312
223
t .start ( ) and
313
224
result instanceof InstanceSource
314
225
or
315
226
exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
316
227
}
317
228
318
229
/** 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 ) }
320
231
321
232
/** 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 ) {
323
234
t .startInAttr ( "add_handlers" ) and
324
235
result = instance ( )
325
236
or
326
237
exists ( DataFlow:: TypeTracker t2 | result = add_handlers ( t2 ) .track ( t2 , t ) )
327
238
}
328
239
329
240
/** 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 ) }
331
242
}
332
243
}
333
244
334
245
// -------------------------------------------------------------------------
335
246
// tornado.httputil
336
247
// -------------------------------------------------------------------------
337
248
/** Gets a reference to the `tornado.httputil` module. */
338
- DataFlow :: Node httputil ( ) { result = tornado_attr ( "httputil" ) }
249
+ API :: Node httputil ( ) { result = tornado_attr ( "httputil" ) }
339
250
340
251
/** Provides models for the `tornado.httputil` module */
341
252
module httputil {
342
253
/**
343
254
* Gets a reference to the attribute `attr_name` of the `tornado.httputil` module.
344
255
* WARNING: Only holds for a few predefined attributes.
345
256
*/
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 ) }
381
258
382
259
/**
383
260
* Provides models for the `tornado.httputil.HttpServerRequest` class
@@ -386,15 +263,7 @@ private module Tornado {
386
263
*/
387
264
module HttpServerRequest {
388
265
/** 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" ) }
398
267
399
268
/**
400
269
* A source of instances of `tornado.httputil.HttpServerRequest`, extend this class to model new instances.
@@ -411,7 +280,7 @@ private module Tornado {
411
280
private class ClassInstantiation extends InstanceSource , DataFlow:: CfgNode {
412
281
override CallNode node ;
413
282
414
- ClassInstantiation ( ) { node . getFunction ( ) = classRef ( ) .asCfgNode ( ) }
283
+ ClassInstantiation ( ) { this = classRef ( ) .getACall ( ) }
415
284
}
416
285
417
286
/** Gets a reference to an instance of `tornado.httputil.HttpServerRequest`. */
0 commit comments