Skip to content

Commit 52d231c

Browse files
authored
Merge pull request #2469 from RasmusWL/python-modernise-twisted-library
Python: modernise twisted library
2 parents eb6feee + 48f873e commit 52d231c

File tree

22 files changed

+225
-76
lines changed

22 files changed

+225
-76
lines changed

python/ql/src/semmle/python/objects/ObjectAPI.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ module Value {
211211
}
212212

213213
/** Gets the `Value` for the integer constant `i`, if it exists.
214-
* There will be no `Value` for most integers, but the following are
214+
* There will be no `Value` for most integers, but the following are
215215
* guaranteed to exist:
216216
* * From zero to 511 inclusive.
217217
* * All powers of 2 (up to 2**30)
@@ -486,6 +486,11 @@ class PythonFunctionValue extends FunctionValue {
486486
)
487487
}
488488

489+
/** Gets a control flow node corresponding to a return statement in this function */
490+
ControlFlowNode getAReturnedNode() {
491+
result = this.getScope().getAReturnValueFlowNode()
492+
}
493+
489494
}
490495

491496
/** Class representing builtin functions, such as `len` or `print` */

python/ql/src/semmle/python/web/flask/Response.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import semmle.python.web.flask.General
99
*/
1010
class FlaskRoutedResponse extends HttpResponseTaintSink {
1111
FlaskRoutedResponse() {
12-
exists(PyFunctionObject response |
13-
flask_routing(_, response.getFunction()) and
12+
exists(PythonFunctionValue response |
13+
flask_routing(_, response.getScope()) and
1414
this = response.getAReturnedNode()
1515
)
1616
}

python/ql/src/semmle/python/web/pyramid/Response.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ private import semmle.python.web.Http
1111
*/
1212
class PyramidRoutedResponse extends HttpResponseTaintSink {
1313
PyramidRoutedResponse() {
14-
exists(PyFunctionObject view |
15-
is_pyramid_view_function(view.getFunction()) and
14+
exists(PythonFunctionValue view |
15+
is_pyramid_view_function(view.getScope()) and
1616
this = view.getAReturnedNode()
1717
)
1818
}
Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,35 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43
import semmle.python.web.Http
54
import Twisted
65

76
/** A twisted.web.http.Request object */
87
class TwistedRequest extends TaintKind {
9-
10-
TwistedRequest() {
11-
this = "twisted.request.http.Request"
12-
}
8+
TwistedRequest() { this = "twisted.request.http.Request" }
139

1410
override TaintKind getTaintOfAttribute(string name) {
1511
result instanceof ExternalStringSequenceDictKind and
16-
(
17-
name = "args"
18-
)
12+
name = "args"
1913
or
2014
result instanceof ExternalStringKind and
21-
(
22-
name = "uri"
23-
)
15+
name = "uri"
2416
}
2517

2618
override TaintKind getTaintOfMethodResult(string name) {
27-
(
28-
name = "getHeader" or
29-
name = "getCookie" or
30-
name = "getUser" or
31-
name = "getPassword"
32-
) and
33-
result instanceof ExternalStringKind
19+
(
20+
name = "getHeader" or
21+
name = "getCookie" or
22+
name = "getUser" or
23+
name = "getPassword"
24+
) and
25+
result instanceof ExternalStringKind
3426
}
35-
3627
}
3728

38-
3929
class TwistedRequestSource extends TaintSource {
30+
TwistedRequestSource() { isTwistedRequestInstance(this) }
4031

41-
TwistedRequestSource() {
42-
isTwistedRequestInstance(this)
43-
}
44-
45-
override string toString() {
46-
result = "Twisted request source"
47-
}
48-
49-
override predicate isSourceOf(TaintKind kind) {
50-
kind instanceof TwistedRequest
51-
}
32+
override string toString() { result = "Twisted request source" }
5233

34+
override predicate isSourceOf(TaintKind kind) { kind instanceof TwistedRequest }
5335
}
Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43
import semmle.python.web.Http
54
import semmle.python.security.strings.Basic
@@ -8,29 +7,25 @@ import Request
87

98
class TwistedResponse extends TaintSink {
109
TwistedResponse() {
11-
exists(PyFunctionObject func, string name |
10+
exists(PythonFunctionValue func, string name, Return ret |
1211
isKnownRequestHandlerMethodName(name) and
1312
name = func.getName() and
1413
func = getTwistedRequestHandlerMethod(name) and
1514
this = func.getAReturnedNode()
1615
)
1716
}
1817

19-
override predicate sinks(TaintKind kind) {
20-
kind instanceof ExternalStringKind
21-
}
18+
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
2219

23-
override string toString() {
24-
result = "Twisted response"
25-
}
20+
override string toString() { result = "Twisted response" }
2621
}
2722

2823
/**
2924
* A sink of taint in the form of a "setter" method on a twisted request
3025
* object, which affects the properties of the subsequent response sent to this
3126
* request.
3227
*/
33-
class TwistedRequestSetter extends HttpResponseTaintSink {
28+
class TwistedRequestSetter extends HttpResponseTaintSink {
3429
TwistedRequestSetter() {
3530
exists(CallNode call, ControlFlowNode node, string name |
3631
(
@@ -44,11 +39,7 @@ class TwistedResponse extends TaintSink {
4439
)
4540
}
4641

47-
override predicate sinks(TaintKind kind) {
48-
kind instanceof ExternalStringKind
49-
}
42+
override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind }
5043

51-
override string toString() {
52-
result = "Twisted request setter"
53-
}
54-
}
44+
override string toString() { result = "Twisted request setter" }
45+
}
Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
import python
2-
32
import semmle.python.security.TaintTracking
43

5-
private ClassObject theTwistedHttpRequestClass() {
6-
result = ModuleObject::named("twisted.web.http").attr("Request")
4+
private ClassValue theTwistedHttpRequestClass() {
5+
result = Value::named("twisted.web.http.Request")
76
}
87

9-
private ClassObject theTwistedHttpResourceClass() {
10-
result = ModuleObject::named("twisted.web.resource").attr("Resource")
8+
private ClassValue theTwistedHttpResourceClass() {
9+
result = Value::named("twisted.web.resource.Resource")
1110
}
1211

13-
ClassObject aTwistedRequestHandlerClass() {
14-
result.getASuperType() = theTwistedHttpResourceClass()
15-
}
12+
ClassValue aTwistedRequestHandlerClass() { result.getABaseType+() = theTwistedHttpResourceClass() }
1613

17-
FunctionObject getTwistedRequestHandlerMethod(string name) {
14+
FunctionValue getTwistedRequestHandlerMethod(string name) {
1815
result = aTwistedRequestHandlerClass().declaredAttribute(name)
1916
}
2017

@@ -24,29 +21,30 @@ predicate isKnownRequestHandlerMethodName(string name) {
2421
name.matches("render_%")
2522
}
2623

27-
/** Holds if `node` is likely to refer to an instance of the twisted
24+
/**
25+
* Holds if `node` is likely to refer to an instance of the twisted
2826
* `Request` class.
2927
*/
3028
predicate isTwistedRequestInstance(NameNode node) {
31-
node.refersTo(_, theTwistedHttpRequestClass(), _)
29+
node.pointsTo().getClass() = theTwistedHttpRequestClass()
3230
or
33-
/* In points-to analysis cannot infer that a given object is an instance of
31+
/*
32+
* In points-to analysis cannot infer that a given object is an instance of
3433
* the `twisted.web.http.Request` class, we also include any parameter
3534
* called `request` that appears inside a subclass of a request handler
3635
* class, and the appropriate arguments of known request handler methods.
3736
*/
38-
exists(Function func | func = node.getScope() |
39-
func.getEnclosingScope().(Class).getClassObject() = aTwistedRequestHandlerClass()
40-
) and
41-
(
42-
/* Any parameter called `request` */
43-
node.getId() = "request" and
44-
node.isParameter()
45-
or
46-
/* Any request parameter of a known request handler method */
47-
exists(FunctionObject func | node.getScope() = func.getFunction() |
37+
38+
exists(Function func |
39+
func = node.getScope() and
40+
func.getEnclosingScope() = aTwistedRequestHandlerClass().getScope()
41+
|
42+
/* Any parameter called `request` */
43+
node.getId() = "request" and
44+
node.isParameter()
45+
or
46+
/* Any request parameter of a known request handler method */
4847
isKnownRequestHandlerMethodName(func.getName()) and
49-
node.getNode() = func.getFunction().getArg(1)
50-
)
48+
node.getNode() = func.getArg(1)
5149
)
5250
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
| class MyRequestHandler1 | test.py:3 |
2+
| class MyRequestHandler2 | test.py:23 |
3+
| class MyRequestHandler3 | test.py:27 |
4+
| class MyRequestHandler4 | test.py:38 |
5+
| class MyRequestHandler5 | test.py:42 |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import python
2+
import semmle.python.TestUtils
3+
import semmle.python.web.twisted.Twisted
4+
5+
from ClassValue cls
6+
where cls = aTwistedRequestHandlerClass()
7+
select cls.toString(), remove_library_prefix(cls.getScope().getLocation())
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| myrender | Function MyRequestHandler2.myrender | test.py:24 |
2+
| render | Function MyRequestHandler1.render | test.py:4 |
3+
| render | Function MyRequestHandler3.render | test.py:28 |
4+
| render | Function MyRequestHandler4.render | test.py:39 |
5+
| render | Function MyRequestHandler5.render | test.py:43 |
6+
| render_GET | Function MyRequestHandler1.render_GET | test.py:9 |
7+
| render_POST | Function MyRequestHandler1.render_POST | test.py:16 |
8+
| render_POST | Function MyRequestHandler3.render_POST | test.py:31 |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import python
2+
import semmle.python.TestUtils
3+
import semmle.python.web.twisted.Twisted
4+
5+
from FunctionValue func, string name
6+
where func = getTwistedRequestHandlerMethod(name)
7+
select name, func.toString(), remove_library_prefix(func.getScope().getLocation())

0 commit comments

Comments
 (0)