Skip to content

Commit 31b3989

Browse files
committed
Python: Handle taint from bytes(obj)
1 parent 1e447c5 commit 31b3989

File tree

3 files changed

+45
-39
lines changed

3 files changed

+45
-39
lines changed

python/ql/src/experimental/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,11 @@ predicate subscriptStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
6767
predicate stringMethods(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
6868
// transforming something tainted into a string will make the string tainted
6969
exists(CallNode call | call = nodeTo.getNode() |
70-
call.getFunction().(NameNode).getId() = "str" and
70+
(
71+
call.getFunction().(NameNode).getId() = "str"
72+
or
73+
call.getFunction().(NameNode).getId() = "bytes"
74+
) and
7175
(
7276
nodeFrom.getNode() = call.getArg(0)
7377
or

python/ql/test/experimental/dataflow/tainttracking/string/TestTaint.expected

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,44 @@
66
| test.py:29 | ok | str_operations | ts[Slice] |
77
| test.py:30 | ok | str_operations | ts[0] |
88
| test.py:31 | ok | str_operations | str(..) |
9-
| test.py:40 | ok | str_methods | ts.capitalize() |
10-
| test.py:41 | ok | str_methods | ts.casefold() |
11-
| test.py:42 | ok | str_methods | ts.center(..) |
12-
| test.py:43 | ok | str_methods | ts.expandtabs() |
13-
| test.py:45 | ok | str_methods | ts.format() |
14-
| test.py:46 | ok | str_methods | "{}".format(..) |
15-
| test.py:47 | ok | str_methods | "{unsafe}".format(..) |
16-
| test.py:49 | ok | str_methods | ts.format_map(..) |
17-
| test.py:50 | fail | str_methods | "{unsafe}".format_map(..) |
18-
| test.py:52 | ok | str_methods | ts.join(..) |
19-
| test.py:53 | fail | str_methods | "".join(..) |
20-
| test.py:55 | ok | str_methods | ts.ljust(..) |
21-
| test.py:56 | ok | str_methods | ts.lstrip() |
22-
| test.py:57 | ok | str_methods | ts.lower() |
23-
| test.py:59 | ok | str_methods | ts.replace(..) |
24-
| test.py:60 | ok | str_methods | "safe".replace(..) |
25-
| test.py:62 | ok | str_methods | ts.rjust(..) |
26-
| test.py:63 | ok | str_methods | ts.rstrip() |
27-
| test.py:64 | ok | str_methods | ts.strip() |
28-
| test.py:65 | ok | str_methods | ts.swapcase() |
29-
| test.py:66 | ok | str_methods | ts.title() |
30-
| test.py:67 | ok | str_methods | ts.upper() |
31-
| test.py:68 | ok | str_methods | ts.zfill(..) |
32-
| test.py:70 | ok | str_methods | ts.encode(..) |
33-
| test.py:71 | ok | str_methods | ts.encode(..).decode(..) |
34-
| test.py:73 | ok | str_methods | tb.decode(..) |
35-
| test.py:74 | ok | str_methods | tb.decode(..).encode(..) |
36-
| test.py:77 | ok | str_methods | ts.partition(..) |
37-
| test.py:78 | ok | str_methods | ts.rpartition(..) |
38-
| test.py:79 | ok | str_methods | ts.rsplit(..) |
39-
| test.py:80 | ok | str_methods | ts.split(..) |
40-
| test.py:81 | ok | str_methods | ts.splitlines() |
41-
| test.py:86 | ok | str_methods | "safe".replace(..) |
42-
| test.py:88 | fail | str_methods | ts.join(..) |
9+
| test.py:32 | ok | str_operations | bytes(..) |
10+
| test.py:41 | ok | str_methods | ts.capitalize() |
11+
| test.py:42 | ok | str_methods | ts.casefold() |
12+
| test.py:43 | ok | str_methods | ts.center(..) |
13+
| test.py:44 | ok | str_methods | ts.expandtabs() |
14+
| test.py:46 | ok | str_methods | ts.format() |
15+
| test.py:47 | ok | str_methods | "{}".format(..) |
16+
| test.py:48 | ok | str_methods | "{unsafe}".format(..) |
17+
| test.py:50 | ok | str_methods | ts.format_map(..) |
18+
| test.py:51 | fail | str_methods | "{unsafe}".format_map(..) |
19+
| test.py:53 | ok | str_methods | ts.join(..) |
20+
| test.py:54 | fail | str_methods | "".join(..) |
21+
| test.py:56 | ok | str_methods | ts.ljust(..) |
22+
| test.py:57 | ok | str_methods | ts.lstrip() |
23+
| test.py:58 | ok | str_methods | ts.lower() |
24+
| test.py:60 | ok | str_methods | ts.replace(..) |
25+
| test.py:61 | ok | str_methods | "safe".replace(..) |
26+
| test.py:63 | ok | str_methods | ts.rjust(..) |
27+
| test.py:64 | ok | str_methods | ts.rstrip() |
28+
| test.py:65 | ok | str_methods | ts.strip() |
29+
| test.py:66 | ok | str_methods | ts.swapcase() |
30+
| test.py:67 | ok | str_methods | ts.title() |
31+
| test.py:68 | ok | str_methods | ts.upper() |
32+
| test.py:69 | ok | str_methods | ts.zfill(..) |
33+
| test.py:71 | ok | str_methods | ts.encode(..) |
34+
| test.py:72 | ok | str_methods | ts.encode(..).decode(..) |
35+
| test.py:74 | ok | str_methods | tb.decode(..) |
36+
| test.py:75 | ok | str_methods | tb.decode(..).encode(..) |
37+
| test.py:78 | ok | str_methods | ts.partition(..) |
38+
| test.py:79 | ok | str_methods | ts.rpartition(..) |
39+
| test.py:80 | ok | str_methods | ts.rsplit(..) |
40+
| test.py:81 | ok | str_methods | ts.split(..) |
41+
| test.py:82 | ok | str_methods | ts.splitlines() |
42+
| test.py:87 | ok | str_methods | "safe".replace(..) |
4343
| test.py:89 | fail | str_methods | ts.join(..) |
44-
| test.py:99 | fail | non_syntactic | meth() |
45-
| test.py:100 | fail | non_syntactic | _str(..) |
46-
| test.py:109 | ok | percent_fmt | BinaryExpr |
44+
| test.py:90 | fail | str_methods | ts.join(..) |
45+
| test.py:100 | fail | non_syntactic | meth() |
46+
| test.py:101 | fail | non_syntactic | _str(..) |
4747
| test.py:110 | ok | percent_fmt | BinaryExpr |
48-
| test.py:111 | fail | percent_fmt | BinaryExpr |
48+
| test.py:111 | ok | percent_fmt | BinaryExpr |
49+
| test.py:112 | fail | percent_fmt | BinaryExpr |

python/ql/test/experimental/dataflow/tainttracking/string/test.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def str_operations():
2929
ts[0:1000],
3030
ts[0],
3131
str(ts),
32+
bytes(ts),
3233
)
3334

3435

0 commit comments

Comments
 (0)