Skip to content

Commit 4c70088

Browse files
authored
Merge pull request #2190 from RasmusWL/python-modernise-tornado-library
Python: modernise tornado library
2 parents b9d1c38 + 5b6675a commit 4c70088

File tree

16 files changed

+143
-110
lines changed

16 files changed

+143
-110
lines changed
Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
1-
/** Provides class representing the `tornado.redirect` function.
1+
/**
2+
* Provides class representing the `tornado.redirect` function.
23
* This module is intended to be imported into a taint-tracking query
34
* to extend `TaintSink`.
45
*/
5-
import python
66

7+
import python
78
import semmle.python.security.TaintTracking
89
import semmle.python.security.strings.Basic
910
import semmle.python.web.Http
1011
import Tornado
1112

12-
1313
/**
1414
* Represents an argument to the `tornado.redirect` function.
1515
*/
1616
class TornadoRedirect extends HttpRedirectTaintSink {
17-
18-
override string toString() {
19-
result = "tornado.redirect"
20-
}
17+
override string toString() { result = "tornado.redirect" }
2118

2219
TornadoRedirect() {
2320
exists(CallNode call, ControlFlowNode node |
@@ -26,5 +23,4 @@ class TornadoRedirect extends HttpRedirectTaintSink {
2623
this = call.getAnArg()
2724
)
2825
}
29-
3026
}
Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43
import semmle.python.web.Http
54
import Tornado
65

76
/** A tornado.request.HttpRequest object */
87
class TornadoRequest extends TaintKind {
9-
10-
TornadoRequest() {
11-
this = "tornado.request.HttpRequest"
12-
}
8+
TornadoRequest() { this = "tornado.request.HttpRequest" }
139

1410
override TaintKind getTaintOfAttribute(string name) {
1511
result instanceof ExternalStringDictKind and
@@ -32,68 +28,45 @@ class TornadoRequest extends TaintKind {
3228
name = "body_arguments"
3329
)
3430
}
35-
3631
}
3732

38-
3933
class TornadoRequestSource extends TaintSource {
34+
TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) }
4035

41-
TornadoRequestSource() {
42-
isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request"))
43-
}
44-
45-
override string toString() {
46-
result = "Tornado request source"
47-
}
48-
49-
override predicate isSourceOf(TaintKind kind) {
50-
kind instanceof TornadoRequest
51-
}
36+
override string toString() { result = "Tornado request source" }
5237

38+
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest }
5339
}
5440

5541
class TornadoExternalInputSource extends TaintSource {
56-
5742
TornadoExternalInputSource() {
5843
exists(string name |
5944
name = "get_argument" or
6045
name = "get_query_argument" or
6146
name = "get_body_argument" or
6247
name = "decode_argument"
63-
|
48+
|
6449
this = callToNamedTornadoRequestHandlerMethod(name)
6550
)
6651
}
6752

68-
override string toString() {
69-
result = "Tornado request method"
70-
}
71-
72-
override predicate isSourceOf(TaintKind kind) {
73-
kind instanceof ExternalStringKind
74-
}
53+
override string toString() { result = "Tornado request method" }
7554

55+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
7656
}
7757

7858
class TornadoExternalInputListSource extends TaintSource {
79-
8059
TornadoExternalInputListSource() {
8160
exists(string name |
8261
name = "get_arguments" or
8362
name = "get_query_arguments" or
8463
name = "get_body_arguments"
85-
|
64+
|
8665
this = callToNamedTornadoRequestHandlerMethod(name)
8766
)
8867
}
8968

90-
override string toString() {
91-
result = "Tornado request method"
92-
}
93-
94-
override predicate isSourceOf(TaintKind kind) {
95-
kind instanceof ExternalStringSequenceKind
96-
}
69+
override string toString() { result = "Tornado request method" }
9770

71+
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
9872
}
99-
Lines changed: 11 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,42 @@
11
import python
2-
3-
42
import semmle.python.security.TaintTracking
53
import semmle.python.security.strings.Basic
64
private import semmle.python.web.Http
7-
85
import Tornado
96

107
class TornadoConnection extends TaintKind {
11-
12-
TornadoConnection() {
13-
this = "tornado.http.connection"
14-
}
15-
8+
TornadoConnection() { this = "tornado.http.connection" }
169
}
1710

1811
class TornadoConnectionSource extends TaintSource {
19-
2012
TornadoConnectionSource() {
2113
isTornadoRequestHandlerInstance(this.(AttrNode).getObject("connection"))
2214
}
2315

24-
override string toString() {
25-
result = "Tornado http connection source"
26-
}
27-
28-
override predicate isSourceOf(TaintKind kind) {
29-
kind instanceof TornadoConnection
30-
}
16+
override string toString() { result = "Tornado http connection source" }
3117

18+
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoConnection }
3219
}
3320

3421
class TornadoConnectionWrite extends HttpResponseTaintSink {
35-
36-
override string toString() {
37-
result = "tornado.connection.write"
38-
}
22+
override string toString() { result = "tornado.connection.write" }
3923

4024
TornadoConnectionWrite() {
4125
exists(CallNode call, ControlFlowNode conn |
4226
conn = call.getFunction().(AttrNode).getObject("write") and
43-
this = call.getAnArg() |
27+
this = call.getAnArg()
28+
|
4429
exists(TornadoConnection tc | tc.taints(conn))
4530
or
4631
isTornadoRequestHandlerInstance(conn)
4732
)
4833
}
4934

50-
override predicate sinks(TaintKind kind) {
51-
kind instanceof StringKind
52-
}
53-
35+
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
5436
}
5537

5638
class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
57-
58-
override string toString() {
59-
result = "tornado.HttpRequesHandler.write"
60-
}
39+
override string toString() { result = "tornado.HttpRequesHandler.write" }
6140

6241
TornadoHttpRequestHandlerWrite() {
6342
exists(CallNode call, ControlFlowNode node |
@@ -67,17 +46,11 @@ class TornadoHttpRequestHandlerWrite extends HttpResponseTaintSink {
6746
)
6847
}
6948

70-
override predicate sinks(TaintKind kind) {
71-
kind instanceof StringKind
72-
}
73-
49+
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
7450
}
7551

7652
class TornadoHttpRequestHandlerRedirect extends HttpResponseTaintSink {
77-
78-
override string toString() {
79-
result = "tornado.HttpRequesHandler.redirect"
80-
}
53+
override string toString() { result = "tornado.HttpRequesHandler.redirect" }
8154

8255
TornadoHttpRequestHandlerRedirect() {
8356
exists(CallNode call, ControlFlowNode node |
@@ -87,11 +60,5 @@ class TornadoHttpRequestHandlerRedirect extends HttpResponseTaintSink {
8760
)
8861
}
8962

90-
override predicate sinks(TaintKind kind) {
91-
kind instanceof StringKind
92-
}
93-
63+
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
9464
}
95-
96-
97-
Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,40 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43
import semmle.python.web.Http
54

6-
private ClassObject theTornadoRequestHandlerClass() {
7-
result = ModuleObject::named("tornado.web").attr("RequestHandler")
8-
}
9-
10-
ClassObject aTornadoRequestHandlerClass() {
11-
result.getASuperType() = theTornadoRequestHandlerClass()
5+
private ClassValue theTornadoRequestHandlerClass() {
6+
result = Value::named("tornado.web.RequestHandler")
127
}
138

14-
FunctionObject getTornadoRequestHandlerMethod(string name) {
15-
result = theTornadoRequestHandlerClass().declaredAttribute(name)
9+
ClassValue aTornadoRequestHandlerClass() {
10+
result.getABaseType+() = theTornadoRequestHandlerClass()
1611
}
1712

18-
/** Holds if `node` is likely to refer to an instance of a tornado
13+
/**
14+
* Holds if `node` is likely to refer to an instance of a tornado
1915
* `RequestHandler` class.
2016
*/
21-
2217
predicate isTornadoRequestHandlerInstance(ControlFlowNode node) {
23-
node.refersTo(_, aTornadoRequestHandlerClass(), _)
18+
node.pointsTo().getClass() = aTornadoRequestHandlerClass()
2419
or
25-
/* In some cases, the points-to analysis won't capture all instances we care
26-
* about. For these, we use the following syntactic check. First, that
27-
* `node` appears inside a method of a subclass of
28-
* `tornado.web.RequestHandler`:*/
29-
node.getScope().getEnclosingScope().(Class).getClassObject() = aTornadoRequestHandlerClass() and
20+
/*
21+
* In some cases, the points-to analysis won't capture all instances we care
22+
* about. For these, we use the following syntactic check. First, that
23+
* `node` appears inside a method of a subclass of
24+
* `tornado.web.RequestHandler`:
25+
*/
26+
27+
node.getScope().getEnclosingScope() = aTornadoRequestHandlerClass().getScope() and
3028
/* Secondly, that `node` refers to the `self` argument: */
31-
node.isLoad() and node.(NameNode).isSelf()
29+
node.isLoad() and
30+
node.(NameNode).isSelf()
3231
}
3332

3433
CallNode callToNamedTornadoRequestHandlerMethod(string name) {
3534
isTornadoRequestHandlerInstance(result.getFunction().(AttrNode).getObject(name))
3635
}
3736

38-
3937
class TornadoCookieSet extends CookieSet, CallNode {
40-
4138
TornadoCookieSet() {
4239
exists(ControlFlowNode f |
4340
f = this.getFunction().(AttrNode).getObject("set_cookie") and
@@ -50,5 +47,4 @@ class TornadoCookieSet extends CookieSet, CallNode {
5047
override ControlFlowNode getKey() { result = this.getArg(0) }
5148

5249
override ControlFlowNode getValue() { result = this.getArg(1) }
53-
5450
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.py:4 | class Handler1 |
2+
| test.py:8 | class Handler2 |
3+
| test.py:14 | class Handler3 |
4+
| test.py:23 | class DeepInheritance |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
import python
3+
4+
import semmle.python.TestUtils
5+
6+
import semmle.python.web.tornado.Tornado
7+
from ClassValue cls
8+
where cls = aTornadoRequestHandlerClass()
9+
select remove_library_prefix(cls.getScope().getLocation()), cls.toString()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.py:6 | Attribute() | externally controlled string |
2+
| test.py:12 | name | externally controlled string |
3+
| test.py:20 | url | externally controlled string |
4+
| test.py:26 | Attribute() | externally controlled string |
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
import python
3+
4+
import semmle.python.web.HttpRequest
5+
import semmle.python.web.HttpResponse
6+
import semmle.python.security.strings.Untrusted
7+
import semmle.python.TestUtils
8+
9+
from TaintSink sink, TaintKind kind
10+
where sink.sinks(kind)
11+
select remove_library_prefix(sink.getLocation()), sink.(ControlFlowNode).getNode().toString(), kind
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.py:6 | Attribute() | externally controlled string |
2+
| test.py:10 | Attribute() | [externally controlled string] |
3+
| test.py:17 | Attribute | tornado.request.HttpRequest |
4+
| test.py:26 | Attribute() | externally controlled string |
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
import python
3+
4+
import semmle.python.TestUtils
5+
6+
import semmle.python.web.HttpRequest
7+
import semmle.python.web.HttpResponse
8+
import semmle.python.security.strings.Untrusted
9+
10+
11+
from TaintSource src, TaintKind kind
12+
where src.isSourceOf(kind)
13+
select remove_library_prefix(src.getLocation()), src.(ControlFlowNode).getNode().toString(), kind

0 commit comments

Comments
 (0)