Skip to content

Commit 5beb681

Browse files
authored
Merge pull request #7087 from RasmusWL/path-injection-fp
Python: Add interesting path-injection FP
2 parents 9f614b1 + f70e4fe commit 5beb681

File tree

2 files changed

+61
-37
lines changed

2 files changed

+61
-37
lines changed

python/ql/test/query-tests/Security/CWE-022-PathInjection/PathInjection.expected

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,22 @@ edges
2121
| path_injection.py:64:13:64:63 | ControlFlowNode for Attribute() | path_injection.py:65:14:65:18 | ControlFlowNode for npath |
2222
| path_injection.py:71:16:71:22 | ControlFlowNode for request | path_injection.py:71:16:71:27 | ControlFlowNode for Attribute |
2323
| path_injection.py:71:16:71:27 | ControlFlowNode for Attribute | path_injection.py:72:13:72:63 | ControlFlowNode for Attribute() |
24-
| path_injection.py:78:20:78:25 | ControlFlowNode for foo_id | path_injection.py:81:14:81:17 | ControlFlowNode for path |
25-
| path_injection.py:85:20:85:22 | ControlFlowNode for foo | path_injection.py:89:14:89:17 | ControlFlowNode for path |
26-
| path_injection.py:94:16:94:22 | ControlFlowNode for request | path_injection.py:94:16:94:27 | ControlFlowNode for Attribute |
27-
| path_injection.py:94:16:94:27 | ControlFlowNode for Attribute | path_injection.py:100:14:100:17 | ControlFlowNode for path |
28-
| path_injection.py:105:16:105:22 | ControlFlowNode for request | path_injection.py:105:16:105:27 | ControlFlowNode for Attribute |
29-
| path_injection.py:105:16:105:27 | ControlFlowNode for Attribute | path_injection.py:111:14:111:17 | ControlFlowNode for path |
30-
| path_injection.py:116:16:116:22 | ControlFlowNode for request | path_injection.py:116:16:116:27 | ControlFlowNode for Attribute |
31-
| path_injection.py:116:16:116:27 | ControlFlowNode for Attribute | path_injection.py:119:14:119:22 | ControlFlowNode for sanitized |
32-
| path_injection.py:125:16:125:22 | ControlFlowNode for request | path_injection.py:125:16:125:27 | ControlFlowNode for Attribute |
33-
| path_injection.py:125:16:125:22 | ControlFlowNode for request | path_injection.py:125:16:125:27 | ControlFlowNode for Attribute |
34-
| path_injection.py:125:16:125:27 | ControlFlowNode for Attribute | path_injection.py:127:30:127:51 | ControlFlowNode for Attribute() |
35-
| path_injection.py:125:16:125:27 | ControlFlowNode for Attribute | path_injection.py:129:14:129:17 | ControlFlowNode for path |
24+
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
25+
| path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:84:16:84:27 | ControlFlowNode for Attribute |
26+
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:86:8:86:44 | ControlFlowNode for Attribute() |
27+
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path |
28+
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path |
29+
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path |
30+
| path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:107:16:107:27 | ControlFlowNode for Attribute |
31+
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | path_injection.py:113:14:113:17 | ControlFlowNode for path |
32+
| path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:118:16:118:27 | ControlFlowNode for Attribute |
33+
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | path_injection.py:124:14:124:17 | ControlFlowNode for path |
34+
| path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:129:16:129:27 | ControlFlowNode for Attribute |
35+
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized |
36+
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
37+
| path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:138:16:138:27 | ControlFlowNode for Attribute |
38+
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:140:30:140:51 | ControlFlowNode for Attribute() |
39+
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | path_injection.py:142:14:142:17 | ControlFlowNode for path |
3640
| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute |
3741
| test.py:9:12:9:18 | ControlFlowNode for request | test.py:9:12:9:23 | ControlFlowNode for Attribute |
3842
| test.py:9:12:9:23 | ControlFlowNode for Attribute | test.py:9:12:9:39 | ControlFlowNode for Attribute() |
@@ -101,25 +105,31 @@ nodes
101105
| path_injection.py:71:16:71:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
102106
| path_injection.py:71:16:71:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
103107
| path_injection.py:72:13:72:63 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
104-
| path_injection.py:78:20:78:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id |
105-
| path_injection.py:81:14:81:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
106-
| path_injection.py:85:20:85:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
107-
| path_injection.py:89:14:89:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
108-
| path_injection.py:94:16:94:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
109-
| path_injection.py:94:16:94:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
110-
| path_injection.py:100:14:100:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
111-
| path_injection.py:105:16:105:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
112-
| path_injection.py:105:16:105:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
113-
| path_injection.py:111:14:111:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
114-
| path_injection.py:116:16:116:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
115-
| path_injection.py:116:16:116:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
116-
| path_injection.py:119:14:119:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized |
117-
| path_injection.py:125:16:125:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
118-
| path_injection.py:125:16:125:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
119-
| path_injection.py:125:16:125:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
120-
| path_injection.py:125:16:125:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
121-
| path_injection.py:127:30:127:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
122-
| path_injection.py:129:14:129:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
108+
| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
109+
| path_injection.py:84:16:84:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
110+
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
111+
| path_injection.py:84:16:84:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
112+
| path_injection.py:86:8:86:44 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
113+
| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | semmle.label | ControlFlowNode for possibly_unsafe_path |
114+
| path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | semmle.label | ControlFlowNode for foo_id |
115+
| path_injection.py:94:14:94:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
116+
| path_injection.py:98:20:98:22 | ControlFlowNode for foo | semmle.label | ControlFlowNode for foo |
117+
| path_injection.py:102:14:102:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
118+
| path_injection.py:107:16:107:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
119+
| path_injection.py:107:16:107:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
120+
| path_injection.py:113:14:113:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
121+
| path_injection.py:118:16:118:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
122+
| path_injection.py:118:16:118:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
123+
| path_injection.py:124:14:124:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
124+
| path_injection.py:129:16:129:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
125+
| path_injection.py:129:16:129:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
126+
| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | semmle.label | ControlFlowNode for sanitized |
127+
| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
128+
| path_injection.py:138:16:138:22 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
129+
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
130+
| path_injection.py:138:16:138:27 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
131+
| path_injection.py:140:30:140:51 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() |
132+
| path_injection.py:142:14:142:17 | ControlFlowNode for path | semmle.label | ControlFlowNode for path |
123133
| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
124134
| test.py:9:12:9:18 | ControlFlowNode for request | semmle.label | ControlFlowNode for request |
125135
| test.py:9:12:9:23 | ControlFlowNode for Attribute | semmle.label | ControlFlowNode for Attribute |
@@ -164,12 +174,13 @@ nodes
164174
| path_injection.py:31:14:31:18 | ControlFlowNode for npath | path_injection.py:27:16:27:22 | ControlFlowNode for request | path_injection.py:31:14:31:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:27:16:27:22 | ControlFlowNode for request | a user-provided value |
165175
| path_injection.py:48:14:48:18 | ControlFlowNode for npath | path_injection.py:46:16:46:22 | ControlFlowNode for request | path_injection.py:48:14:48:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:46:16:46:22 | ControlFlowNode for request | a user-provided value |
166176
| path_injection.py:65:14:65:18 | ControlFlowNode for npath | path_injection.py:63:16:63:22 | ControlFlowNode for request | path_injection.py:65:14:65:18 | ControlFlowNode for npath | This path depends on $@. | path_injection.py:63:16:63:22 | ControlFlowNode for request | a user-provided value |
167-
| path_injection.py:81:14:81:17 | ControlFlowNode for path | path_injection.py:78:20:78:25 | ControlFlowNode for foo_id | path_injection.py:81:14:81:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:78:20:78:25 | ControlFlowNode for foo_id | a user-provided value |
168-
| path_injection.py:89:14:89:17 | ControlFlowNode for path | path_injection.py:85:20:85:22 | ControlFlowNode for foo | path_injection.py:89:14:89:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:85:20:85:22 | ControlFlowNode for foo | a user-provided value |
169-
| path_injection.py:100:14:100:17 | ControlFlowNode for path | path_injection.py:94:16:94:22 | ControlFlowNode for request | path_injection.py:100:14:100:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:94:16:94:22 | ControlFlowNode for request | a user-provided value |
170-
| path_injection.py:111:14:111:17 | ControlFlowNode for path | path_injection.py:105:16:105:22 | ControlFlowNode for request | path_injection.py:111:14:111:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:105:16:105:22 | ControlFlowNode for request | a user-provided value |
171-
| path_injection.py:119:14:119:22 | ControlFlowNode for sanitized | path_injection.py:116:16:116:22 | ControlFlowNode for request | path_injection.py:119:14:119:22 | ControlFlowNode for sanitized | This path depends on $@. | path_injection.py:116:16:116:22 | ControlFlowNode for request | a user-provided value |
172-
| path_injection.py:129:14:129:17 | ControlFlowNode for path | path_injection.py:125:16:125:22 | ControlFlowNode for request | path_injection.py:129:14:129:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:125:16:125:22 | ControlFlowNode for request | a user-provided value |
177+
| path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | path_injection.py:84:16:84:22 | ControlFlowNode for request | path_injection.py:87:18:87:37 | ControlFlowNode for possibly_unsafe_path | This path depends on $@. | path_injection.py:84:16:84:22 | ControlFlowNode for request | a user-provided value |
178+
| path_injection.py:94:14:94:17 | ControlFlowNode for path | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | path_injection.py:94:14:94:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:91:20:91:25 | ControlFlowNode for foo_id | a user-provided value |
179+
| path_injection.py:102:14:102:17 | ControlFlowNode for path | path_injection.py:98:20:98:22 | ControlFlowNode for foo | path_injection.py:102:14:102:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:98:20:98:22 | ControlFlowNode for foo | a user-provided value |
180+
| path_injection.py:113:14:113:17 | ControlFlowNode for path | path_injection.py:107:16:107:22 | ControlFlowNode for request | path_injection.py:113:14:113:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:107:16:107:22 | ControlFlowNode for request | a user-provided value |
181+
| path_injection.py:124:14:124:17 | ControlFlowNode for path | path_injection.py:118:16:118:22 | ControlFlowNode for request | path_injection.py:124:14:124:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:118:16:118:22 | ControlFlowNode for request | a user-provided value |
182+
| path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | path_injection.py:129:16:129:22 | ControlFlowNode for request | path_injection.py:132:14:132:22 | ControlFlowNode for sanitized | This path depends on $@. | path_injection.py:129:16:129:22 | ControlFlowNode for request | a user-provided value |
183+
| path_injection.py:142:14:142:17 | ControlFlowNode for path | path_injection.py:138:16:138:22 | ControlFlowNode for request | path_injection.py:142:14:142:17 | ControlFlowNode for path | This path depends on $@. | path_injection.py:138:16:138:22 | ControlFlowNode for request | a user-provided value |
173184
| test.py:19:10:19:10 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:19:10:19:10 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |
174185
| test.py:26:10:26:10 | ControlFlowNode for y | test.py:9:12:9:18 | ControlFlowNode for request | test.py:26:10:26:10 | ControlFlowNode for y | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |
175186
| test.py:33:14:33:14 | ControlFlowNode for x | test.py:9:12:9:18 | ControlFlowNode for request | test.py:33:14:33:14 | ControlFlowNode for x | This path depends on $@. | test.py:9:12:9:18 | ControlFlowNode for request | a user-provided value |

python/ql/test/query-tests/Security/CWE-022-PathInjection/path_injection.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ def safe_path_abspath():
7474
f = open(npath) # OK
7575

7676

77+
@app.route("/abspath_tricky")
78+
def safe_path_abspath_tricky():
79+
# Normalized (by `abspath`), and checked properly. The tricky bit is that the
80+
# possibly unsafe path is the being used in the `open` call, but only if it is known
81+
# to be safe.
82+
#
83+
# FP for CVE-2021-41185
84+
filename = request.args.get('filename', '')
85+
possibly_unsafe_path = os.path.join(STATIC_DIR, filename)
86+
if os.path.abspath(possibly_unsafe_path).startswith(STATIC_DIR):
87+
f = open(possibly_unsafe_path) # OK
88+
89+
7790
@app.route("/int-only/<int:foo_id>")
7891
def flask_int_only(foo_id):
7992
# This is OK, since the flask routing ensures that `foo_id` MUST be an integer.

0 commit comments

Comments
 (0)