Skip to content

Commit 12113e9

Browse files
authored
Merge pull request #2603 from RasmusWL/python-fix-http-source-sink
Python: Make web libs use HttpRequestTaintSource and HttpResponseTaintSink
2 parents de45b1a + d5c6092 commit 12113e9

File tree

103 files changed

+324
-381
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+324
-381
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Improvements to Python analysis
2+
3+
The following changes in version 1.24 affect Python analysis in all applications.
4+
5+
## General improvements
6+
7+
## New queries
8+
9+
| **Query** | **Tags** | **Purpose** |
10+
|-----------------------------|-----------|--------------------------------------------------------------------|
11+
12+
## Changes to existing queries
13+
14+
| **Query** | **Expected impact** | **Change** |
15+
|----------------------------|------------------------|------------------------------------------------------------------|
16+
17+
### Web framework support
18+
19+
The QL-library support for the web frameworks Bottle, CherryPy, Falcon, Pyramid, TurboGears, Tornado, and Twisted have
20+
been fixed so they provide a proper HttpRequestTaintSource, instead of a TaintSource. This will enable results for the following queries:
21+
22+
- py/path-injection
23+
- py/command-line-injection
24+
- py/reflective-xss
25+
- py/sql-injection
26+
- py/code-injection
27+
- py/unsafe-deserialization
28+
- py/url-redirection
29+
30+
The QL-library support for the web framework Twisted have been fixed so they provide a proper
31+
HttpResponseTaintSink, instead of a TaintSink. This will enable results for the following
32+
queries:
33+
34+
- py/reflective-xss
35+
- py/stack-trace-exposure
36+
37+
## Changes to libraries

python/ql/src/semmle/python/web/bottle/Request.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class BottleRequestKind extends TaintKind {
2121
}
2222
}
2323

24-
private class RequestSource extends TaintSource {
24+
private class RequestSource extends HttpRequestTaintSource {
2525
RequestSource() { this.(ControlFlowNode).pointsTo(theBottleRequestObject()) }
2626

2727
override predicate isSourceOf(TaintKind kind) { kind instanceof BottleRequestKind }
@@ -69,7 +69,7 @@ class UntrustedFile extends TaintKind {
6969
// Move UntrustedFile to shared location
7070
//
7171
/** Parameter to a bottle request handler function */
72-
class BottleRequestParameter extends TaintSource {
72+
class BottleRequestParameter extends HttpRequestTaintSource {
7373
BottleRequestParameter() {
7474
exists(BottleRoute route | route.getNamedArgument() = this.(ControlFlowNode).getNode())
7575
}

python/ql/src/semmle/python/web/cherrypy/Request.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class CherryPyRequest extends TaintKind {
2525
}
2626
}
2727

28-
class CherryPyExposedFunctionParameter extends TaintSource {
28+
class CherryPyExposedFunctionParameter extends HttpRequestTaintSource {
2929
CherryPyExposedFunctionParameter() {
3030
exists(Parameter p |
3131
p = any(CherryPyExposedFunction f).getAnArg() and
@@ -39,7 +39,7 @@ class CherryPyExposedFunctionParameter extends TaintSource {
3939
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
4040
}
4141

42-
class CherryPyRequestSource extends TaintSource {
42+
class CherryPyRequestSource extends HttpRequestTaintSource {
4343
CherryPyRequestSource() { this.(ControlFlowNode).pointsTo(Value::named("cherrypy.request")) }
4444

4545
override predicate isSourceOf(TaintKind kind) { kind instanceof CherryPyRequest }

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ private ClassValue theDjangoHttpResponseClass() {
1818
not result = theDjangoHttpRedirectClass()
1919
}
2020

21-
/** Instantiation of a django response. */
22-
class DjangoResponseSource extends TaintSource {
21+
/** internal class used for tracking a django response. */
22+
private class DjangoResponseSource extends TaintSource {
2323
DjangoResponseSource() {
2424
exists(ClassValue cls |
2525
cls.getASuperType() = theDjangoHttpResponseClass() and

python/ql/src/semmle/python/web/falcon/Request.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class FalconRequest extends TaintKind {
3535
}
3636
}
3737

38-
class FalconRequestParameter extends TaintSource {
38+
class FalconRequestParameter extends HttpRequestTaintSource {
3939
FalconRequestParameter() {
4040
exists(FalconHandlerFunction f | f.getRequest() = this.(ControlFlowNode).getNode())
4141
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ class FalconResponse extends TaintKind {
99
FalconResponse() { this = "falcon.response" }
1010
}
1111

12-
class FalconResponseParameter extends TaintSource {
12+
/** Only used internally to track the response parameter */
13+
private class FalconResponseParameter extends TaintSource {
1314
FalconResponseParameter() {
1415
exists(FalconHandlerFunction f | f.getResponse() = this.(ControlFlowNode).getNode())
1516
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class FlaskRequestArgs extends HttpRequestTaintSource {
4747
}
4848

4949
/** Source of dictionary whose values are externally controlled */
50-
class FlaskRequestJson extends TaintSource {
50+
class FlaskRequestJson extends HttpRequestTaintSource {
5151
FlaskRequestJson() { flask_request_attr(this, "json") }
5252

5353
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalJsonKind }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class PyramidRequest extends BaseWebobRequest {
1111
}
1212

1313
/** Source of pyramid request objects */
14-
class PyramidViewArgument extends TaintSource {
14+
class PyramidViewArgument extends HttpRequestTaintSource {
1515
PyramidViewArgument() {
1616
exists(Function view_func |
1717
is_pyramid_view_function(view_func) and

python/ql/src/semmle/python/web/tornado/Redirect.qll

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ import Tornado
1313
/**
1414
* Represents an argument to the `tornado.redirect` function.
1515
*/
16-
class TornadoRedirect extends HttpRedirectTaintSink {
17-
override string toString() { result = "tornado.redirect" }
16+
class TornadoHttpRequestHandlerRedirect extends HttpRedirectTaintSink {
17+
override string toString() { result = "tornado.HttpRequestHandler.redirect" }
1818

19-
TornadoRedirect() {
19+
TornadoHttpRequestHandlerRedirect() {
2020
exists(CallNode call, ControlFlowNode node |
2121
node = call.getFunction().(AttrNode).getObject("redirect") and
2222
isTornadoRequestHandlerInstance(node) and
23-
this = call.getAnArg()
23+
this = call.getArg(0)
2424
)
2525
}
26+
27+
override predicate sinks(TaintKind kind) { kind instanceof StringKind }
2628
}

python/ql/src/semmle/python/web/tornado/Request.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ class TornadoRequest extends TaintKind {
3030
}
3131
}
3232

33-
class TornadoRequestSource extends TaintSource {
33+
class TornadoRequestSource extends HttpRequestTaintSource {
3434
TornadoRequestSource() { isTornadoRequestHandlerInstance(this.(AttrNode).getObject("request")) }
3535

3636
override string toString() { result = "Tornado request source" }
3737

3838
override predicate isSourceOf(TaintKind kind) { kind instanceof TornadoRequest }
3939
}
4040

41-
class TornadoExternalInputSource extends TaintSource {
41+
class TornadoExternalInputSource extends HttpRequestTaintSource {
4242
TornadoExternalInputSource() {
4343
exists(string name |
4444
name = "get_argument" or
@@ -55,7 +55,7 @@ class TornadoExternalInputSource extends TaintSource {
5555
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
5656
}
5757

58-
class TornadoExternalInputListSource extends TaintSource {
58+
class TornadoExternalInputListSource extends HttpRequestTaintSource {
5959
TornadoExternalInputListSource() {
6060
exists(string name |
6161
name = "get_arguments" or

0 commit comments

Comments
 (0)