mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge pull request #9001 from RasmusWL/files-refactoring
Python: Flask: Improve `request.files` modeing
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
The modeling of `request.files` in Flask has been fixed, so we now properly handle
|
||||||
|
assignments to local variables (such as `files = request.files; files['key'].filename`).
|
||||||
@@ -411,21 +411,16 @@ module Flask {
|
|||||||
/** An `FileStorage` instance that originates from a flask request. */
|
/** An `FileStorage` instance that originates from a flask request. */
|
||||||
private class FlaskRequestFileStorageInstances extends Werkzeug::FileStorage::InstanceSource {
|
private class FlaskRequestFileStorageInstances extends Werkzeug::FileStorage::InstanceSource {
|
||||||
FlaskRequestFileStorageInstances() {
|
FlaskRequestFileStorageInstances() {
|
||||||
// TODO: this currently only works in local-scope, since writing type-trackers for
|
|
||||||
// this is a little too much effort. Once API-graphs are available for more
|
|
||||||
// things, we can rewrite this.
|
|
||||||
//
|
|
||||||
// TODO: This approach for identifying member-access is very adhoc, and we should
|
// TODO: This approach for identifying member-access is very adhoc, and we should
|
||||||
// be able to do something more structured for providing modeling of the members
|
// be able to do something more structured for providing modeling of the members
|
||||||
// of a container-object.
|
// of a container-object.
|
||||||
exists(DataFlow::AttrRead files | files = request().getMember("files").getAnImmediateUse() |
|
exists(API::Node files | files = request().getMember("files") |
|
||||||
this.asCfgNode().(SubscriptNode).getObject() = files.asCfgNode()
|
this.asCfgNode().(SubscriptNode).getObject() = files.getAUse().asCfgNode()
|
||||||
or
|
or
|
||||||
this.(DataFlow::MethodCallNode).calls(files, "get")
|
this = files.getMember("get").getACall()
|
||||||
or
|
or
|
||||||
exists(DataFlow::MethodCallNode getlistCall | getlistCall.calls(files, "getlist") |
|
this.asCfgNode().(SubscriptNode).getObject() =
|
||||||
this.asCfgNode().(SubscriptNode).getObject() = getlistCall.asCfgNode()
|
files.getMember("getlist").getReturn().getAUse().asCfgNode()
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,6 +189,7 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route
|
|||||||
a = request.args
|
a = request.args
|
||||||
b = a
|
b = a
|
||||||
gl = b.getlist
|
gl = b.getlist
|
||||||
|
files = request.files
|
||||||
ensure_tainted(
|
ensure_tainted(
|
||||||
request.args, # $ tainted
|
request.args, # $ tainted
|
||||||
a, # $ tainted
|
a, # $ tainted
|
||||||
@@ -202,6 +203,8 @@ def test_taint(name = "World!", number="0", foo="foo"): # $requestHandler route
|
|||||||
a.getlist('key'), # $ tainted
|
a.getlist('key'), # $ tainted
|
||||||
b.getlist('key'), # $ tainted
|
b.getlist('key'), # $ tainted
|
||||||
gl('key'), # $ tainted
|
gl('key'), # $ tainted
|
||||||
|
|
||||||
|
files.get('key').filename, # $ tainted
|
||||||
)
|
)
|
||||||
|
|
||||||
# aliasing tests
|
# aliasing tests
|
||||||
|
|||||||
Reference in New Issue
Block a user