Python: Shared taint tracking: Handle string concat + subcript

This commit is contained in:
Rasmus Wriedt Larsen
2020-08-20 17:07:10 +02:00
parent 61f89ca3c3
commit a77f118b62
2 changed files with 42 additions and 13 deletions

View File

@@ -3,13 +3,6 @@ private import experimental.dataflow.DataFlow
private import experimental.dataflow.internal.DataFlowPrivate
private import experimental.dataflow.internal.TaintTrackingPublic
/**
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
* different objects.
*/
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { none() }
/**
* Holds if `node` should be a barrier in all global taint flow configurations
* but not in local taint.
@@ -25,3 +18,39 @@ predicate defaultAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nod
or
any(AdditionalTaintStep a).step(nodeFrom, nodeTo)
}
/**
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
* different objects.
*/
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
concatStep(nodeFrom, nodeTo)
or
subscriptStep(nodeFrom, nodeTo)
}
/**
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to concatenation.
*
* Note that since we cannot easily distinguish interesting types (like string, list, tuple), so
* we consider any `+` operation to propagate taint. After consulting with the JS team, this
* should doesn't sound like it is a big problem in practice.
*/
predicate concatStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
exists(BinaryExprNode add | add = nodeTo.getNode() |
add.getOp() instanceof Add and
(
add.getLeft() = nodeFrom.getNode()
or
add.getRight() = nodeFrom.getNode()
)
)
}
/**
* Holds if taint can flow from `nodeFrom` to `nodeTo` with a step related to subscripting.
*/
predicate subscriptStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
nodeTo.getNode().(SubscriptNode).getObject() = nodeFrom.getNode()
}

View File

@@ -1,10 +1,10 @@
| test.py:24 | ok | str_operations | ts |
| test.py:25 | fail | str_operations | BinaryExpr |
| test.py:26 | fail | str_operations | BinaryExpr |
| test.py:27 | fail | str_operations | ts[Slice] |
| test.py:28 | fail | str_operations | ts[Slice] |
| test.py:29 | fail | str_operations | ts[Slice] |
| test.py:30 | fail | str_operations | ts[0] |
| test.py:25 | ok | str_operations | BinaryExpr |
| test.py:26 | ok | str_operations | BinaryExpr |
| test.py:27 | ok | str_operations | ts[Slice] |
| test.py:28 | ok | str_operations | ts[Slice] |
| test.py:29 | ok | str_operations | ts[Slice] |
| test.py:30 | ok | str_operations | ts[0] |
| test.py:31 | fail | str_operations | str(..) |
| test.py:40 | fail | str_methods | ts.capitalize() |
| test.py:41 | fail | str_methods | ts.casefold() |