Skip to content

Commit 768932d

Browse files
committed
Python: Add tainttracking step that was removed
when the correpsonding datadlow step was removed.
1 parent 07d5086 commit 768932d

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/TaintTrackingPrivate.qll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ private module Cached {
5353
DataFlowPrivate::iterableUnpackingStoreStep(nodeFrom, _, nodeTo)
5454
or
5555
awaitStep(nodeFrom, nodeTo)
56+
or
57+
asyncWithStep(nodeFrom, nodeTo)
5658
}
5759
}
5860

@@ -211,3 +213,24 @@ predicate copyStep(DataFlow::CfgNode nodeFrom, DataFlow::CfgNode nodeTo) {
211213
predicate awaitStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
212214
nodeTo.asExpr().(Await).getValue() = nodeFrom.asExpr()
213215
}
216+
217+
/**
218+
* Holds if taint can flow from `nodeFrom` to `nodeTo` inside an `async with` statement.
219+
*
220+
* For example in
221+
* ```python
222+
* async with open("foo") as f:
223+
* ```
224+
* the variable `f` is tainted if the result of `open("foo")` is tainted.
225+
*/
226+
predicate asyncWithStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
227+
exists(With with, ControlFlowNode contextManager, ControlFlowNode var |
228+
nodeFrom.(DataFlow::CfgNode).getNode() = contextManager and
229+
nodeTo.(DataFlow::EssaNode).getVar().getDefinition().(WithDefinition).getDefiningNode() = var and
230+
// see `with_flow` in `python/ql/src/semmle/python/dataflow/Implementation.qll`
231+
with.getContextExpr() = contextManager.getNode() and
232+
with.getOptionalVars() = var.getNode() and
233+
with.isAsync() and
234+
contextManager.strictlyDominates(var)
235+
)
236+
}

python/ql/test/experimental/dataflow/tainttracking/defaultAdditionalTaintStep/test_async.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ async def test_async_with():
3131
ctx = AsyncContext()
3232
taint(ctx)
3333
async with ctx as tainted:
34-
ensure_tainted(tainted) # $ MISSING: tainted
34+
ensure_tainted(tainted) # $ tainted
3535

3636

3737
class AsyncIter:

0 commit comments

Comments
 (0)