Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: minorAnalysis
---

- The modelling of Flask requests (as sources of user-controlled data) has been improved. Rather than treating `from flask import request` as a source of remote flow, the modelling now behaves as if the first occurrence (inside a request handler) of a reference to that `request` object is a source of remote flow. This makes it much easier to understand alert messages that refer to the source of remote flow.
13 changes: 12 additions & 1 deletion python/ql/lib/semmle/python/frameworks/Flask.qll
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,18 @@ module Flask {
* See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Request
*/
private class FlaskRequestSource extends RemoteFlowSource::Range {
FlaskRequestSource() { this = request().asSource() }
FlaskRequestSource() {
// Using `request().asSource()` would result in data-flow paths starting at the import of
// `request`, which is not very useful. Instead, we look at all the places this `request`
// object can flow, and use only those that are local sources (so we only get the first
// instance of `request` in a function), expressions (so we don't get any SSA entry
// definitions), and which don't correspond to an `ImportMember` (so we don't get the
// `from flask import request` occurrence).
this = request().getAValueReachableFromSource() and
this instanceof DataFlow::LocalSourceNode and
this instanceof DataFlow::ExprNode and
not this.asExpr() instanceof ImportMember
}

override string getSourceType() { result = "flask.request" }
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
edges
| UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for request | provenance | |
| UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for request | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | provenance | |
| UnsafeUnpack.py:11:7:11:14 | ControlFlowNode for filename | UnsafeUnpack.py:13:24:13:58 | ControlFlowNode for Attribute() | provenance | AdditionalTaintStep |
| UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | provenance | AdditionalTaintStep |
| UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | UnsafeUnpack.py:11:18:11:49 | ControlFlowNode for Attribute() | provenance | Config |
Expand Down Expand Up @@ -93,8 +91,6 @@ edges
| UnsafeUnpack.py:194:53:194:55 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:31 | ControlFlowNode for tmp | provenance | |
| UnsafeUnpack.py:201:29:201:31 | ControlFlowNode for tmp | UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | provenance | Config |
nodes
| UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | semmle.label | ControlFlowNode for ImportMember |
| UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| UnsafeUnpack.py:11:7:11:14 | ControlFlowNode for filename | semmle.label | ControlFlowNode for filename |
| UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
| UnsafeUnpack.py:11:18:11:29 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
Expand Down Expand Up @@ -189,7 +185,7 @@ nodes
| UnsafeUnpack.py:201:29:201:36 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
subpaths
#select
| UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | UnsafeUnpack.py:5:26:5:32 | ControlFlowNode for ImportMember | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | Unsafe extraction from a malicious tarball retrieved from a remote location. |
| UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | UnsafeUnpack.py:11:18:11:24 | ControlFlowNode for request | UnsafeUnpack.py:19:35:19:41 | ControlFlowNode for tarpath | Unsafe extraction from a malicious tarball retrieved from a remote location. |
| UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | UnsafeUnpack.py:33:50:33:65 | ControlFlowNode for local_ziped_path | UnsafeUnpack.py:34:23:34:38 | ControlFlowNode for local_ziped_path | Unsafe extraction from a malicious tarball retrieved from a remote location. |
| UnsafeUnpack.py:48:23:48:37 | ControlFlowNode for compressed_file | UnsafeUnpack.py:47:20:47:34 | ControlFlowNode for compressed_file | UnsafeUnpack.py:48:23:48:37 | ControlFlowNode for compressed_file | Unsafe extraction from a malicious tarball retrieved from a remote location. |
| UnsafeUnpack.py:52:23:52:37 | ControlFlowNode for compressed_file | UnsafeUnpack.py:51:19:51:36 | ControlFlowNode for Attribute() | UnsafeUnpack.py:52:23:52:37 | ControlFlowNode for compressed_file | Unsafe extraction from a malicious tarball retrieved from a remote location. |
Expand Down
Loading