Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 87f31a9

Browse files
committed
Python: Add flask_attr helper
1 parent bfc29bb commit 87f31a9

1 file changed

Lines changed: 41 additions & 10 deletions

File tree

  • python/ql/src/experimental/semmle/python/frameworks

python/ql/src/experimental/semmle/python/frameworks/Flask.qll

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ private import experimental.semmle.python.frameworks.Werkzeug
1515
* See https://flask.palletsprojects.com/en/1.1.x/.
1616
*/
1717
private module FlaskModel {
18+
// ---------------------------------------------------------------------------
19+
// flask
20+
// ---------------------------------------------------------------------------
1821
/** Gets a reference to the `flask` module. */
1922
private DataFlow::Node flask(DataFlow::TypeTracker t) {
2023
t.start() and
@@ -26,21 +29,49 @@ private module FlaskModel {
2629
/** Gets a reference to the `flask` module. */
2730
DataFlow::Node flask() { result = flask(DataFlow::TypeTracker::end()) }
2831

29-
/** Provides models for the `flask` module. */
30-
module flask {
31-
/** Gets a reference to the `flask.request` object. */
32-
private DataFlow::Node request(DataFlow::TypeTracker t) {
32+
/**
33+
* Gets a reference to the attribute `attr_name` of the `flask` module.
34+
* WARNING: Only holds for a few predefined attributes.
35+
*/
36+
private DataFlow::Node flask_attr(DataFlow::TypeTracker t, string attr_name) {
37+
attr_name in ["request"] and
38+
(
3339
t.start() and
34-
result = DataFlow::importNode("flask.request")
40+
result = DataFlow::importNode("flask" + "." + attr_name)
3541
or
36-
t.startInAttr("request") and
42+
t.startInAttr(attr_name) and
3743
result = flask()
38-
or
39-
exists(DataFlow::TypeTracker t2 | result = request(t2).track(t2, t))
40-
}
44+
)
45+
or
46+
// Due to bad performance when using normal setup with `flask_attr(t2, attr_name).track(t2, t)`
47+
// we have inlined that code and forced a join
48+
exists(DataFlow::TypeTracker t2 |
49+
exists(DataFlow::StepSummary summary |
50+
flask_attr_first_join(t2, attr_name, result, summary) and
51+
t = t2.append(summary)
52+
)
53+
)
54+
}
55+
56+
pragma[nomagic]
57+
private predicate flask_attr_first_join(
58+
DataFlow::TypeTracker t2, string attr_name, DataFlow::Node res, DataFlow::StepSummary summary
59+
) {
60+
DataFlow::StepSummary::step(flask_attr(t2, attr_name), res, summary)
61+
}
62+
63+
/**
64+
* Gets a reference to the attribute `attr_name` of the `flask` module.
65+
* WARNING: Only holds for a few predefined attributes.
66+
*/
67+
private DataFlow::Node flask_attr(string attr_name) {
68+
result = flask_attr(DataFlow::TypeTracker::end(), attr_name)
69+
}
4170

71+
/** Provides models for the `flask` module. */
72+
module flask {
4273
/** Gets a reference to the `flask.request` object. */
43-
DataFlow::Node request() { result = request(DataFlow::TypeTracker::end()) }
74+
DataFlow::Node request() { result = flask_attr("request") }
4475

4576
/**
4677
* Provides models for the `flask.Flask` class

0 commit comments

Comments
 (0)