Python: Add tests of path-graph for dataflow/taint-tracking

Although this is actually using taint-tracking (so we can use the +=
statement), I would personally forget to check under the
dataflow/tainttracking folder to look for such a test, so I'm opting to
keep it under the dataflow/ folder.
This commit is contained in:
Rasmus Wriedt Larsen
2023-08-09 10:25:52 +02:00
parent 01ff690d51
commit 9bd5694c3f
3 changed files with 132 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -0,0 +1,34 @@
/**
* @kind path-problem
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import experimental.dataflow.testConfig
import TestUtilities.InlineExpectationsTest
module TestTaintFlow = TaintTracking::Global<TestConfig>;
module PathNodeTest implements TestSig {
string getARelevantTag() { result = "path-node" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(TestTaintFlow::PathNode pn |
location = pn.getNode().getLocation() and
tag = "path-node" and
value = "" and
element = pn.toString()
)
}
}
import MakeTest<PathNodeTest>
// running the query to inspect the results can be quite nice!
// just uncomment these lines!
// import TestTaintFlow::PathGraph
// from TestTaintFlow::PathNode source, TestTaintFlow::PathNode sink
// where TestTaintFlow::flowPath(source, sink)
// select sink.getNode(), source, sink,
// sink.getNode().getEnclosingCallable().toString() + ": --> " +
// sink.getNode().getLocation().getStartLine().toString()

View File

@@ -0,0 +1,96 @@
def assign():
x = SOURCE # $ path-node
y = x
SINK(y) # $ path-node
def aug_assign():
x = SOURCE # $ path-node
z = ""
z += x
SINK(z) # $ path-node
def dont_use_rhs(cond):
# liked noted in the original Ruby PR: https://github.com/github/codeql/pull/12566
x = SOURCE # $ path-node
if cond:
y = x
SINK(x) # $ path-node
def flow_through_function():
def identify(x): # $ path-node
return x # $ path-node
x = SOURCE # $ path-node
y = identify(x) # $ path-node
SINK(y) # $ path-node
def attribute():
class X: pass
x = X()
x.attr = SOURCE # $ path-node
y = x
SINK(y.attr) # $ path-node
def list_loop():
x = SOURCE # $ path-node
l = list()
l.append(x) # $ path-node
for y in l: # $ path-node
SINK(y) # $ path-node
def list_index():
x = SOURCE # $ path-node
l = list()
l.append(x) # $ path-node
z = l[0] # $ path-node
SINK(z) # $ path-node
def test_tuple():
x = SOURCE # $ path-node
y = ((x, 1), 2) # $ path-node
(z, _), _ = y # $ path-node
SINK(z) # $ path-node
def test_with():
x = SOURCE # $ path-node
with x as y:
SINK(y) # $ path-node
def test_match():
x = SOURCE # $ path-node
match x:
case y:
SINK(y) # $ path-node