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

Skip to content

Commit 423139b

Browse files
committed
Python: Add additional taint steps for iterable-unpacking
1 parent afb160f commit 423139b

3 files changed

Lines changed: 59 additions & 43 deletions

File tree

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
3838
copyStep(nodeFrom, nodeTo)
3939
or
4040
forStep(nodeFrom, nodeTo)
41+
or
42+
unpackingAssignmentStep(nodeFrom, nodeTo)
4143
}
4244

4345
/**
@@ -205,3 +207,17 @@ predicate forStep(DataFlow::CfgNode nodeFrom, DataFlow::EssaNode nodeTo) {
205207
nodeFrom.getNode().getNode() = for.getIter()
206208
)
207209
}
210+
211+
212+
/**
213+
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to iterable unpacking.
214+
* Only handles normal assignment (`x,y = calc_point()`), since `for x,y in points` is handled by `forStep`.
215+
*/
216+
predicate unpackingAssignmentStep(DataFlow::CfgNode nodeFrom, DataFlow::EssaNode nodeTo) {
217+
// `a, b = myiterable` or `head, *tail = myiterable` (only Python 3)
218+
exists(MultiAssignmentDefinition defn, Assign assign |
219+
assign.getATarget().contains(defn.getDefiningNode().getNode()) and
220+
nodeTo.getVar() = defn and
221+
nodeFrom.getNode().getNode() = assign.getValue()
222+
)
223+
}

python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep-py3/TestTaint.expected

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
| string.py:39 | fail | binary_decode_encode | base64.encodebytes(..) |
1010
| string.py:40 | fail | binary_decode_encode | base64.decodebytes(..) |
1111
| string.py:48 | ok | f_strings | Fstring |
12-
| unpacking.py:18 | fail | extended_unpacking | first |
13-
| unpacking.py:18 | fail | extended_unpacking | last |
14-
| unpacking.py:18 | fail | extended_unpacking | rest |
15-
| unpacking.py:23 | fail | also_allowed | a |
12+
| unpacking.py:18 | ok | extended_unpacking | first |
13+
| unpacking.py:18 | ok | extended_unpacking | last |
14+
| unpacking.py:18 | ok | extended_unpacking | rest |
15+
| unpacking.py:23 | ok | also_allowed | a |
1616
| unpacking.py:31 | ok | also_allowed | b |
1717
| unpacking.py:31 | ok | also_allowed | c |
18-
| unpacking.py:39 | fail | nested | x |
19-
| unpacking.py:39 | fail | nested | xs |
20-
| unpacking.py:39 | fail | nested | ys |
18+
| unpacking.py:39 | ok | nested | x |
19+
| unpacking.py:39 | ok | nested | xs |
20+
| unpacking.py:39 | ok | nested | ys |

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

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
| collections.py:55 | ok | test_access | next(..) |
2121
| collections.py:56 | ok | test_access | copy(..) |
2222
| collections.py:57 | ok | test_access | deepcopy(..) |
23-
| collections.py:61 | fail | test_access | a |
24-
| collections.py:61 | fail | test_access | b |
25-
| collections.py:61 | fail | test_access | c |
23+
| collections.py:61 | ok | test_access | a |
24+
| collections.py:61 | ok | test_access | b |
25+
| collections.py:61 | ok | test_access | c |
2626
| collections.py:64 | ok | test_access | h |
2727
| collections.py:66 | ok | test_access | i |
2828
| collections.py:73 | ok | test_dict_access | tainted_dict["name"] |
@@ -114,36 +114,36 @@
114114
| string.py:150 | fail | binary_decode_encode | base64.decodestring(..) |
115115
| string.py:155 | fail | binary_decode_encode | quopri.encodestring(..) |
116116
| string.py:156 | fail | binary_decode_encode | quopri.decodestring(..) |
117-
| unpacking.py:16 | fail | unpacking | a |
118-
| unpacking.py:16 | fail | unpacking | b |
119-
| unpacking.py:16 | fail | unpacking | c |
120-
| unpacking.py:22 | fail | unpacking_to_list | a |
121-
| unpacking.py:22 | fail | unpacking_to_list | b |
122-
| unpacking.py:22 | fail | unpacking_to_list | c |
123-
| unpacking.py:31 | fail | nested | a1 |
124-
| unpacking.py:31 | fail | nested | a2 |
125-
| unpacking.py:31 | fail | nested | a3 |
126-
| unpacking.py:31 | fail | nested | b |
127-
| unpacking.py:31 | fail | nested | c |
128-
| unpacking.py:35 | fail | nested | a1 |
129-
| unpacking.py:35 | fail | nested | a2 |
130-
| unpacking.py:35 | fail | nested | a3 |
131-
| unpacking.py:35 | fail | nested | b |
132-
| unpacking.py:35 | fail | nested | c |
133-
| unpacking.py:39 | fail | nested | a1 |
134-
| unpacking.py:39 | fail | nested | a2 |
135-
| unpacking.py:39 | fail | nested | a3 |
136-
| unpacking.py:39 | fail | nested | b |
137-
| unpacking.py:39 | fail | nested | c |
138-
| unpacking.py:46 | fail | unpack_from_set | a |
139-
| unpacking.py:46 | fail | unpack_from_set | b |
140-
| unpacking.py:46 | fail | unpack_from_set | c |
141-
| unpacking.py:56 | fail | contrived_1 | a |
142-
| unpacking.py:56 | fail | contrived_1 | b |
143-
| unpacking.py:56 | fail | contrived_1 | c |
144-
| unpacking.py:57 | ok | contrived_1 | d |
145-
| unpacking.py:57 | ok | contrived_1 | e |
146-
| unpacking.py:57 | ok | contrived_1 | f |
147-
| unpacking.py:65 | fail | contrived_2 | a |
148-
| unpacking.py:65 | fail | contrived_2 | b |
149-
| unpacking.py:65 | fail | contrived_2 | c |
117+
| unpacking.py:16 | ok | unpacking | a |
118+
| unpacking.py:16 | ok | unpacking | b |
119+
| unpacking.py:16 | ok | unpacking | c |
120+
| unpacking.py:22 | ok | unpacking_to_list | a |
121+
| unpacking.py:22 | ok | unpacking_to_list | b |
122+
| unpacking.py:22 | ok | unpacking_to_list | c |
123+
| unpacking.py:31 | ok | nested | a1 |
124+
| unpacking.py:31 | ok | nested | a2 |
125+
| unpacking.py:31 | ok | nested | a3 |
126+
| unpacking.py:31 | ok | nested | b |
127+
| unpacking.py:31 | ok | nested | c |
128+
| unpacking.py:35 | ok | nested | a1 |
129+
| unpacking.py:35 | ok | nested | a2 |
130+
| unpacking.py:35 | ok | nested | a3 |
131+
| unpacking.py:35 | ok | nested | b |
132+
| unpacking.py:35 | ok | nested | c |
133+
| unpacking.py:39 | ok | nested | a1 |
134+
| unpacking.py:39 | ok | nested | a2 |
135+
| unpacking.py:39 | ok | nested | a3 |
136+
| unpacking.py:39 | ok | nested | b |
137+
| unpacking.py:39 | ok | nested | c |
138+
| unpacking.py:46 | ok | unpack_from_set | a |
139+
| unpacking.py:46 | ok | unpack_from_set | b |
140+
| unpacking.py:46 | ok | unpack_from_set | c |
141+
| unpacking.py:56 | ok | contrived_1 | a |
142+
| unpacking.py:56 | ok | contrived_1 | b |
143+
| unpacking.py:56 | ok | contrived_1 | c |
144+
| unpacking.py:57 | fail | contrived_1 | d |
145+
| unpacking.py:57 | fail | contrived_1 | e |
146+
| unpacking.py:57 | fail | contrived_1 | f |
147+
| unpacking.py:65 | ok | contrived_2 | a |
148+
| unpacking.py:65 | ok | contrived_2 | b |
149+
| unpacking.py:65 | ok | contrived_2 | c |

0 commit comments

Comments
 (0)