Python: Add additional taint steps for iterable-unpacking

This commit is contained in:
Rasmus Wriedt Larsen
2020-08-26 20:21:15 +02:00
parent afb160fbbb
commit 423139bc22
3 changed files with 59 additions and 43 deletions

View File

@@ -38,6 +38,8 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
copyStep(nodeFrom, nodeTo)
or
forStep(nodeFrom, nodeTo)
or
unpackingAssignmentStep(nodeFrom, nodeTo)
}
/**
@@ -205,3 +207,17 @@ predicate forStep(DataFlow::CfgNode nodeFrom, DataFlow::EssaNode nodeTo) {
nodeFrom.getNode().getNode() = for.getIter()
)
}
/**
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to iterable unpacking.
* Only handles normal assignment (`x,y = calc_point()`), since `for x,y in points` is handled by `forStep`.
*/
predicate unpackingAssignmentStep(DataFlow::CfgNode nodeFrom, DataFlow::EssaNode nodeTo) {
// `a, b = myiterable` or `head, *tail = myiterable` (only Python 3)
exists(MultiAssignmentDefinition defn, Assign assign |
assign.getATarget().contains(defn.getDefiningNode().getNode()) and
nodeTo.getVar() = defn and
nodeFrom.getNode().getNode() = assign.getValue()
)
}

View File

@@ -9,12 +9,12 @@
| string.py:39 | fail | binary_decode_encode | base64.encodebytes(..) |
| string.py:40 | fail | binary_decode_encode | base64.decodebytes(..) |
| string.py:48 | ok | f_strings | Fstring |
| unpacking.py:18 | fail | extended_unpacking | first |
| unpacking.py:18 | fail | extended_unpacking | last |
| unpacking.py:18 | fail | extended_unpacking | rest |
| unpacking.py:23 | fail | also_allowed | a |
| unpacking.py:18 | ok | extended_unpacking | first |
| unpacking.py:18 | ok | extended_unpacking | last |
| unpacking.py:18 | ok | extended_unpacking | rest |
| unpacking.py:23 | ok | also_allowed | a |
| unpacking.py:31 | ok | also_allowed | b |
| unpacking.py:31 | ok | also_allowed | c |
| unpacking.py:39 | fail | nested | x |
| unpacking.py:39 | fail | nested | xs |
| unpacking.py:39 | fail | nested | ys |
| unpacking.py:39 | ok | nested | x |
| unpacking.py:39 | ok | nested | xs |
| unpacking.py:39 | ok | nested | ys |

View File

@@ -20,9 +20,9 @@
| collections.py:55 | ok | test_access | next(..) |
| collections.py:56 | ok | test_access | copy(..) |
| collections.py:57 | ok | test_access | deepcopy(..) |
| collections.py:61 | fail | test_access | a |
| collections.py:61 | fail | test_access | b |
| collections.py:61 | fail | test_access | c |
| collections.py:61 | ok | test_access | a |
| collections.py:61 | ok | test_access | b |
| collections.py:61 | ok | test_access | c |
| collections.py:64 | ok | test_access | h |
| collections.py:66 | ok | test_access | i |
| collections.py:73 | ok | test_dict_access | tainted_dict["name"] |
@@ -114,36 +114,36 @@
| string.py:150 | fail | binary_decode_encode | base64.decodestring(..) |
| string.py:155 | fail | binary_decode_encode | quopri.encodestring(..) |
| string.py:156 | fail | binary_decode_encode | quopri.decodestring(..) |
| unpacking.py:16 | fail | unpacking | a |
| unpacking.py:16 | fail | unpacking | b |
| unpacking.py:16 | fail | unpacking | c |
| unpacking.py:22 | fail | unpacking_to_list | a |
| unpacking.py:22 | fail | unpacking_to_list | b |
| unpacking.py:22 | fail | unpacking_to_list | c |
| unpacking.py:31 | fail | nested | a1 |
| unpacking.py:31 | fail | nested | a2 |
| unpacking.py:31 | fail | nested | a3 |
| unpacking.py:31 | fail | nested | b |
| unpacking.py:31 | fail | nested | c |
| unpacking.py:35 | fail | nested | a1 |
| unpacking.py:35 | fail | nested | a2 |
| unpacking.py:35 | fail | nested | a3 |
| unpacking.py:35 | fail | nested | b |
| unpacking.py:35 | fail | nested | c |
| unpacking.py:39 | fail | nested | a1 |
| unpacking.py:39 | fail | nested | a2 |
| unpacking.py:39 | fail | nested | a3 |
| unpacking.py:39 | fail | nested | b |
| unpacking.py:39 | fail | nested | c |
| unpacking.py:46 | fail | unpack_from_set | a |
| unpacking.py:46 | fail | unpack_from_set | b |
| unpacking.py:46 | fail | unpack_from_set | c |
| unpacking.py:56 | fail | contrived_1 | a |
| unpacking.py:56 | fail | contrived_1 | b |
| unpacking.py:56 | fail | contrived_1 | c |
| unpacking.py:57 | ok | contrived_1 | d |
| unpacking.py:57 | ok | contrived_1 | e |
| unpacking.py:57 | ok | contrived_1 | f |
| unpacking.py:65 | fail | contrived_2 | a |
| unpacking.py:65 | fail | contrived_2 | b |
| unpacking.py:65 | fail | contrived_2 | c |
| unpacking.py:16 | ok | unpacking | a |
| unpacking.py:16 | ok | unpacking | b |
| unpacking.py:16 | ok | unpacking | c |
| unpacking.py:22 | ok | unpacking_to_list | a |
| unpacking.py:22 | ok | unpacking_to_list | b |
| unpacking.py:22 | ok | unpacking_to_list | c |
| unpacking.py:31 | ok | nested | a1 |
| unpacking.py:31 | ok | nested | a2 |
| unpacking.py:31 | ok | nested | a3 |
| unpacking.py:31 | ok | nested | b |
| unpacking.py:31 | ok | nested | c |
| unpacking.py:35 | ok | nested | a1 |
| unpacking.py:35 | ok | nested | a2 |
| unpacking.py:35 | ok | nested | a3 |
| unpacking.py:35 | ok | nested | b |
| unpacking.py:35 | ok | nested | c |
| unpacking.py:39 | ok | nested | a1 |
| unpacking.py:39 | ok | nested | a2 |
| unpacking.py:39 | ok | nested | a3 |
| unpacking.py:39 | ok | nested | b |
| unpacking.py:39 | ok | nested | c |
| unpacking.py:46 | ok | unpack_from_set | a |
| unpacking.py:46 | ok | unpack_from_set | b |
| unpacking.py:46 | ok | unpack_from_set | c |
| unpacking.py:56 | ok | contrived_1 | a |
| unpacking.py:56 | ok | contrived_1 | b |
| unpacking.py:56 | ok | contrived_1 | c |
| unpacking.py:57 | fail | contrived_1 | d |
| unpacking.py:57 | fail | contrived_1 | e |
| unpacking.py:57 | fail | contrived_1 | f |
| unpacking.py:65 | ok | contrived_2 | a |
| unpacking.py:65 | ok | contrived_2 | b |
| unpacking.py:65 | ok | contrived_2 | c |