Merge pull request #9001 from RasmusWL/files-refactoring

Python: Flask: Improve `request.files` modeing
This commit is contained in:
yoff
2022-05-03 12:19:55 +02:00
committed by GitHub
3 changed files with 13 additions and 10 deletions

View File

@@ -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`).

View File

@@ -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()
)
) )
} }
} }

View File

@@ -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