mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
Python: Shared taint tracking: Handle string concat + subcript
This commit is contained in:
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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() |
|
||||
|
||||
Reference in New Issue
Block a user