Python: Update more inline expectation tests to use the paramterized module

This commit is contained in:
Jeroen Ketema
2023-06-15 16:44:04 +02:00
parent c53e529bac
commit dba4460526
153 changed files with 551 additions and 379 deletions

View File

@@ -3,12 +3,10 @@ import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowQueryTest extends InlineExpectationsTest {
DataFlowQueryTest() { this = "DataFlowQueryTest" }
module DataFlowQueryTest implements TestSig {
string getARelevantTag() { result = "result" }
override string getARelevantTag() { result = "result" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Configuration cfg, DataFlow::Node sink | cfg.hasFlowTo(sink) |
location = sink.getLocation() and
tag = "result" and
@@ -22,7 +20,7 @@ class DataFlowQueryTest extends InlineExpectationsTest {
// Sometimes a line contains both an alert and a safe sink.
// In this situation, the annotation form `OK(safe sink)`
// can be useful.
override predicate hasOptionalResult(Location location, string element, string tag, string value) {
predicate hasOptionalResult(Location location, string element, string tag, string value) {
exists(DataFlow::Configuration cfg, DataFlow::Node sink |
cfg.isSink(sink) or cfg.isSink(sink, _)
|
@@ -34,6 +32,8 @@ class DataFlowQueryTest extends InlineExpectationsTest {
}
}
import MakeTest<DataFlowQueryTest>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: result=BAD` or `result=OK` annotation" and
exists(DataFlow::Node sink |
@@ -42,13 +42,13 @@ query predicate missingAnnotationOnSink(Location location, string error, string
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not exists(DataFlow::Configuration cfg | cfg.hasFlowTo(sink)) and
not exists(FalseNegativeExpectation missingResult |
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "result" and
missingResult.getValue() = "BAD" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
) and
not exists(GoodExpectation okResult |
not exists(GoodTestExpectation okResult |
okResult.getTag() = "result" and
okResult.getValue() in ["OK", "OK(" + prettyNode(sink) + ")"] and
okResult.getLocation().getFile() = location.getFile() and

View File

@@ -3,22 +3,21 @@ import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
abstract class FlowTest extends InlineExpectationsTest {
bindingset[this]
FlowTest() { any() }
signature module FlowTestSig {
string flowTag();
abstract string flowTag();
predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
}
abstract predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
private module FlowTest<FlowTestSig Impl> implements TestSig {
string getARelevantTag() { result = Impl::flowTag() }
override string getARelevantTag() { result = this.flowTag() }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode | this.relevantFlow(fromNode, toNode) |
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode | Impl::relevantFlow(fromNode, toNode) |
location = toNode.getLocation() and
tag = this.flowTag() and
tag = Impl::flowTag() and
value =
"\"" + prettyNode(fromNode).replaceAll("\"", "'") + this.lineStr(fromNode, toNode) + " -> " +
"\"" + prettyNode(fromNode).replaceAll("\"", "'") + lineStr(fromNode, toNode) + " -> " +
prettyNode(toNode).replaceAll("\"", "'") + "\"" and
element = toNode.toString()
)
@@ -38,3 +37,11 @@ abstract class FlowTest extends InlineExpectationsTest {
)
}
}
module MakeFlowTest<FlowTestSig Impl> {
import MakeTest<FlowTest<Impl>>
}
module MakeFlowTest2<FlowTestSig Impl1, FlowTestSig Impl2> {
import MakeTest<MergeTests<FlowTest<Impl1>, FlowTest<Impl2>>>
}

View File

@@ -2,12 +2,12 @@ import python
import semmle.python.dataflow.new.DataFlow
import FlowTest
class LocalFlowStepTest extends FlowTest {
LocalFlowStepTest() { this = "LocalFlowStepTest" }
module LocalFlowStepTest implements FlowTestSig {
string flowTag() { result = "step" }
override string flowTag() { result = "step" }
override predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) {
predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) {
DataFlow::localFlowStep(fromNode, toNode)
}
}
import MakeFlowTest<LocalFlowStepTest>

View File

@@ -3,25 +3,23 @@ import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.internal.DataFlowPrivate
import FlowTest
class MaximalFlowTest extends FlowTest {
MaximalFlowTest() { this = "MaximalFlowTest" }
module MaximalFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
source != sink and
exists(MaximalFlowsConfig cfg | cfg.hasFlow(source, sink))
MaximalFlows::flow(source, sink)
}
}
import MakeFlowTest<MaximalFlowTest>
/**
* A configuration to find all "maximal" flows.
* To be used on small programs.
*/
class MaximalFlowsConfig extends DataFlow::Configuration {
MaximalFlowsConfig() { this = "MaximalFlowsConfig" }
override predicate isSource(DataFlow::Node node) {
module MaximalFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
exists(node.getLocation().getFile().getRelativePath()) and
not node.asCfgNode() instanceof CallNode and
not node.asCfgNode().getNode() instanceof Return and
@@ -32,7 +30,7 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
not DataFlow::localFlowStep(_, node)
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(node.getLocation().getFile().getRelativePath()) and
not any(CallNode c).getArg(_) = node.asCfgNode() and
not node instanceof DataFlow::ArgumentNode and
@@ -40,3 +38,5 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
not DataFlow::localFlowStep(node, _)
}
}
module MaximalFlows = DataFlow::Global<MaximalFlowsConfig>;

View File

@@ -3,20 +3,20 @@ import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testConfig
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
module DataFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
TestFlow::flow(source, sink)
}
}
import MakeFlowTest<DataFlowTest>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
exists(DataFlow::Node sink |
any(TestConfiguration config).isSink(sink) and
TestConfig::isSink(sink) and
// note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually.
exists(DataFlow::CallCfgNode call |
call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and
@@ -24,8 +24,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string
) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not any(TestConfiguration config).hasFlow(_, sink) and
not exists(FalseNegativeExpectation missingResult |
not TestFlow::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "flow" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()

View File

@@ -3,16 +3,16 @@ import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testTaintConfig
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
module DataFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
TestFlow::flow(source, sink)
}
}
import MakeFlowTest<DataFlowTest>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
exists(DataFlow::Node sink |
@@ -23,8 +23,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string
) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not any(TestConfiguration config).hasFlow(_, sink) and
not exists(FalseNegativeExpectation missingResult |
not TestFlow::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "flow" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()

View File

@@ -4,11 +4,11 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
private import semmle.python.ApiGraphs
import TestUtilities.InlineExpectationsTest
class UnresolvedCallExpectations extends InlineExpectationsTest {
UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" }
override string getARelevantTag() { result = "unresolved_call" }
signature module UnresolvedCallExpectationsSig {
predicate unresolvedCall(CallNode call);
}
module DefaultUnresolvedCallExpectations implements UnresolvedCallExpectationsSig {
predicate unresolvedCall(CallNode call) {
not exists(DataFlowPrivate::DataFlowCall dfc |
exists(dfc.getCallable()) and dfc.getNode() = call
@@ -16,14 +16,22 @@ class UnresolvedCallExpectations extends InlineExpectationsTest {
not DataFlowPrivate::resolveClassCall(call, _) and
not call = API::builtin(_).getACall().asCfgNode()
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CallNode call | this.unresolvedCall(call) |
location = call.getLocation() and
tag = "unresolved_call" and
value = prettyExpr(call.getNode()) and
element = call.toString()
)
}
}
module MakeUnresolvedCallExpectations<UnresolvedCallExpectationsSig Impl> {
private module UnresolvedCallExpectations implements TestSig {
string getARelevantTag() { result = "unresolved_call" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CallNode call | Impl::unresolvedCall(call) |
location = call.getLocation() and
tag = "unresolved_call" and
value = prettyExpr(call.getNode()) and
element = call.toString()
)
}
}
import MakeTest<UnresolvedCallExpectations>
}

View File

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

View File

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

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

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

View File

@@ -2,11 +2,13 @@ import python
import experimental.dataflow.TestUtil.UnresolvedCalls
private import semmle.python.dataflow.new.DataFlow
class IgnoreDictMethod extends UnresolvedCallExpectations {
override predicate unresolvedCall(CallNode call) {
super.unresolvedCall(call) and
module IgnoreDictMethod implements UnresolvedCallExpectationsSig {
predicate unresolvedCall(CallNode call) {
DefaultUnresolvedCallExpectations::unresolvedCall(call) and
not any(DataFlow::MethodCallNode methodCall |
methodCall.getMethodName() in ["get", "setdefault"]
).asCfgNode() = call
}
}
import MakeUnresolvedCallExpectations<IgnoreDictMethod>

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

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

View File

@@ -4,12 +4,10 @@ import experimental.dataflow.TestUtil.FlowTest
private import semmle.python.dataflow.new.internal.PrintNode
private import semmle.python.dataflow.new.internal.DataFlowPrivate as DP
class ImportTimeLocalFlowTest extends FlowTest {
ImportTimeLocalFlowTest() { this = "ImportTimeLocalFlowTest" }
module ImportTimeLocalFlowTest implements FlowTestSig {
string flowTag() { result = "importTimeFlow" }
override string flowTag() { result = "importTimeFlow" }
override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and
// results are displayed next to `nodeTo`, so we need a line to write on
nodeTo.getLocation().getStartLine() > 0 and
@@ -18,12 +16,10 @@ class ImportTimeLocalFlowTest extends FlowTest {
}
}
class RuntimeLocalFlowTest extends FlowTest {
RuntimeLocalFlowTest() { this = "RuntimeLocalFlowTest" }
module RuntimeLocalFlowTest implements FlowTestSig {
string flowTag() { result = "runtimeFlow" }
override string flowTag() { result = "runtimeFlow" }
override predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
predicate relevantFlow(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
nodeFrom.getLocation().getFile().getBaseName() = "multiphase.py" and
// results are displayed next to `nodeTo`, so we need a line to write on
nodeTo.getLocation().getStartLine() > 0 and
@@ -34,3 +30,5 @@ class RuntimeLocalFlowTest extends FlowTest {
DP::runtimeJumpStep(nodeFrom, nodeTo)
}
}
import MakeFlowTest2<ImportTimeLocalFlowTest, RuntimeLocalFlowTest>

View File

@@ -9,5 +9,5 @@ import python
import experimental.dataflow.testConfig
from DataFlow::Node source, DataFlow::Node sink
where exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
where TestFlow::flow(source, sink)
select source, sink

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

@@ -4,7 +4,7 @@
import python
import semmle.python.dataflow.new.FlowSummary
import DataFlow::PathGraph
import TestFlow::PathGraph
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.internal.FlowSummaryImpl
import semmle.python.ApiGraphs
@@ -16,6 +16,6 @@ query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c)
Private::External::invalidSpecComponent(s, c)
}
from DataFlow::PathNode source, DataFlow::PathNode sink, TestConfiguration conf
where conf.hasFlowPath(source, sink)
from TestFlow::PathNode source, TestFlow::PathNode sink
where TestFlow::flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1,6 +1,12 @@
import experimental.meta.InlineTaintTest
import semmle.python.dataflow.new.BarrierGuards
class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
override predicate isSanitizer(DataFlow::Node node) { node instanceof StringConstCompareBarrier }
module CustomSanitizerOverridesConfig implements DataFlow::ConfigSig {
predicate isSource = TestTaintTrackingConfig::isSource/1;
predicate isSink = TestTaintTrackingConfig::isSink/1;
predicate isBarrier(DataFlow::Node node) { node instanceof StringConstCompareBarrier }
}
import MakeInlineTaintTest<CustomSanitizerOverridesConfig>

View File

@@ -1,25 +1,26 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures
isSanitizer
| TestTaintTrackingConfiguration | test.py:21:39:21:39 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test.py:34:39:34:39 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() |
| TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:40:28:40:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:111:28:111:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:130:28:130:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:137:28:137:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:167:24:167:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:185:24:185:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s |
| TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s |
| test.py:21:39:21:39 | ControlFlowNode for s |
| test.py:34:39:34:39 | ControlFlowNode for s |
| test.py:52:28:52:28 | ControlFlowNode for s |
| test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() |
| test_logical.py:33:28:33:28 | ControlFlowNode for s |
| test_logical.py:40:28:40:28 | ControlFlowNode for s |
| test_logical.py:48:28:48:28 | ControlFlowNode for s |
| test_logical.py:53:28:53:28 | ControlFlowNode for s |
| test_logical.py:92:28:92:28 | ControlFlowNode for s |
| test_logical.py:103:28:103:28 | ControlFlowNode for s |
| test_logical.py:111:28:111:28 | ControlFlowNode for s |
| test_logical.py:130:28:130:28 | ControlFlowNode for s |
| test_logical.py:137:28:137:28 | ControlFlowNode for s |
| test_logical.py:148:28:148:28 | ControlFlowNode for s |
| test_logical.py:151:28:151:28 | ControlFlowNode for s |
| test_logical.py:158:28:158:28 | ControlFlowNode for s |
| test_logical.py:167:24:167:24 | ControlFlowNode for s |
| test_logical.py:176:24:176:24 | ControlFlowNode for s |
| test_logical.py:185:24:185:24 | ControlFlowNode for s |
| test_logical.py:193:24:193:24 | ControlFlowNode for s |
| test_reference.py:31:28:31:28 | ControlFlowNode for s |

View File

@@ -12,8 +12,12 @@ predicate isUnsafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean bra
branch = false
}
class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
override predicate isSanitizer(DataFlow::Node node) {
module CustomSanitizerOverridesConfig implements DataFlow::ConfigSig {
predicate isSource = TestTaintTrackingConfig::isSource/1;
predicate isSink = TestTaintTrackingConfig::isSink/1;
predicate isBarrier(DataFlow::Node node) {
exists(Call call |
call.getFunc().(Name).getId() = "emulated_authentication_check" and
call.getArg(0) = node.asExpr()
@@ -27,7 +31,9 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration {
}
}
query predicate isSanitizer(TestTaintTrackingConfiguration conf, DataFlow::Node node) {
import MakeInlineTaintTest<CustomSanitizerOverridesConfig>
query predicate isSanitizer(DataFlow::Node node) {
exists(node.getLocation().getFile().getRelativePath()) and
conf.isSanitizer(node)
CustomSanitizerOverridesConfig::isBarrier(node)
}

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -23,10 +23,8 @@
private import python
import semmle.python.dataflow.new.DataFlow
class TestConfiguration extends DataFlow::Configuration {
TestConfiguration() { this = "TestConfiguration" }
override predicate isSource(DataFlow::Node node) {
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "SOURCE"
or
node.(DataFlow::CfgNode).getNode().getNode().(StrConst).getS() = "source"
@@ -37,7 +35,7 @@ class TestConfiguration extends DataFlow::Configuration {
// No support for complex numbers
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(DataFlow::CallCfgNode call |
call.getFunction().asCfgNode().(NameNode).getId() in ["SINK", "SINK_F"] and
(node = call.getArg(_) or node = call.getArgByName(_)) and
@@ -45,5 +43,7 @@ class TestConfiguration extends DataFlow::Configuration {
)
}
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
module TestFlow = DataFlow::Global<TestConfig>;

View File

@@ -24,10 +24,8 @@ private import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
class TestConfiguration extends TaintTracking::Configuration {
TestConfiguration() { this = "TestConfiguration" }
override predicate isSource(DataFlow::Node node) {
module TestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "SOURCE"
or
node.(DataFlow::CfgNode).getNode().getNode().(StrConst).getS() = "source"
@@ -38,12 +36,14 @@ class TestConfiguration extends TaintTracking::Configuration {
// No support for complex numbers
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() in ["SINK", "SINK_F"] and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
override predicate isSanitizerIn(DataFlow::Node node) { this.isSource(node) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
module TestFlow = TaintTracking::Global<TestConfig>;

View File

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

View File

@@ -14,12 +14,10 @@ private DataFlow::TypeTrackingNode tracked(TypeTracker t) {
exists(TypeTracker t2 | result = tracked(t2).track(t2, t))
}
class TrackedTest extends InlineExpectationsTest {
TrackedTest() { this = "TrackedTest" }
module TrackedTest implements TestSig {
string getARelevantTag() { result = "tracked" }
override string getARelevantTag() { result = "tracked" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node e, TypeTracker t |
tracked(t).flowsTo(e) and
// Module variables have no sensible location, and hence can't be annotated.
@@ -54,12 +52,10 @@ private DataFlow::TypeTrackingNode string_type(TypeTracker t) {
exists(TypeTracker t2 | result = string_type(t2).track(t2, t))
}
class TrackedIntTest extends InlineExpectationsTest {
TrackedIntTest() { this = "TrackedIntTest" }
module TrackedIntTest implements TestSig {
string getARelevantTag() { result = "int" }
override string getARelevantTag() { result = "int" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node e, TypeTracker t |
int_type(t).flowsTo(e) and
tag = "int" and
@@ -70,12 +66,10 @@ class TrackedIntTest extends InlineExpectationsTest {
}
}
class TrackedStringTest extends InlineExpectationsTest {
TrackedStringTest() { this = "TrackedStringTest" }
module TrackedStringTest implements TestSig {
string getARelevantTag() { result = "str" }
override string getARelevantTag() { result = "str" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node e, TypeTracker t |
string_type(t).flowsTo(e) and
tag = "str" and
@@ -100,12 +94,10 @@ private DataFlow::TypeTrackingNode tracked_self(TypeTracker t) {
exists(TypeTracker t2 | result = tracked_self(t2).track(t2, t))
}
class TrackedSelfTest extends InlineExpectationsTest {
TrackedSelfTest() { this = "TrackedSelfTest" }
module TrackedSelfTest implements TestSig {
string getARelevantTag() { result = "tracked_self" }
override string getARelevantTag() { result = "tracked_self" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node e, TypeTracker t |
tracked_self(t).flowsTo(e) and
// Module variables have no sensible location, and hence can't be annotated.
@@ -161,12 +153,10 @@ private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) {
/** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */
DataFlow::Node foo_bar_baz() { foo_bar_baz(DataFlow::TypeTracker::end()).flowsTo(result) }
class TrackedFooBarBaz extends InlineExpectationsTest {
TrackedFooBarBaz() { this = "TrackedFooBarBaz" }
module TrackedFooBarBaz implements TestSig {
string getARelevantTag() { result = "tracked_foo_bar_baz" }
override string getARelevantTag() { result = "tracked_foo_bar_baz" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node e |
e = foo_bar_baz() and
// Module variables have no sensible location, and hence can't be annotated.
@@ -178,3 +168,5 @@ class TrackedFooBarBaz extends InlineExpectationsTest {
)
}
}
import MakeTest<MergeTests5<TrackedTest, TrackedIntTest, TrackedStringTest, TrackedSelfTest, TrackedFooBarBaz>>

View File

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

View File

@@ -7,7 +7,7 @@ module CaptureTest implements TestSig {
string getARelevantTag() { result = "captured" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node sink | exists(TestConfiguration cfg | cfg.hasFlowTo(sink)) |
exists(DataFlow::Node sink | TestFlow::flowTo(sink) |
location = sink.getLocation() and
tag = "captured" and
value = "" and

View File

@@ -4,12 +4,10 @@ import semmle.python.Concepts
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
class SystemCommandExecutionTest extends InlineExpectationsTest {
SystemCommandExecutionTest() { this = "SystemCommandExecutionTest" }
module SystemCommandExecutionTest implements TestSig {
string getARelevantTag() { result = "getCommand" }
override string getARelevantTag() { result = "getCommand" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SystemCommandExecution sce, DataFlow::Node command |
command = sce.getCommand() and
@@ -21,14 +19,12 @@ class SystemCommandExecutionTest extends InlineExpectationsTest {
}
}
class DecodingTest extends InlineExpectationsTest {
DecodingTest() { this = "DecodingTest" }
override string getARelevantTag() {
module DecodingTest implements TestSig {
string getARelevantTag() {
result in ["decodeInput", "decodeOutput", "decodeFormat", "decodeMayExecuteInput"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Decoding d |
exists(DataFlow::Node data |
@@ -61,12 +57,10 @@ class DecodingTest extends InlineExpectationsTest {
}
}
class EncodingTest extends InlineExpectationsTest {
EncodingTest() { this = "EncodingTest" }
module EncodingTest implements TestSig {
string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
override string getARelevantTag() { result in ["encodeInput", "encodeOutput", "encodeFormat"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Encoding e |
exists(DataFlow::Node data |
@@ -93,12 +87,10 @@ class EncodingTest extends InlineExpectationsTest {
}
}
class LoggingTest extends InlineExpectationsTest {
LoggingTest() { this = "LoggingTest" }
module LoggingTest implements TestSig {
string getARelevantTag() { result = "loggingInput" }
override string getARelevantTag() { result = "loggingInput" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Logging logging, DataFlow::Node data |
location = data.getLocation() and
@@ -110,12 +102,10 @@ class LoggingTest extends InlineExpectationsTest {
}
}
class CodeExecutionTest extends InlineExpectationsTest {
CodeExecutionTest() { this = "CodeExecutionTest" }
module CodeExecutionTest implements TestSig {
string getARelevantTag() { result = "getCode" }
override string getARelevantTag() { result = "getCode" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CodeExecution ce, DataFlow::Node code |
exists(location.getFile().getRelativePath()) and
@@ -128,12 +118,10 @@ class CodeExecutionTest extends InlineExpectationsTest {
}
}
class SqlConstructionTest extends InlineExpectationsTest {
SqlConstructionTest() { this = "SqlConstructionTest" }
module SqlConstructionTest implements TestSig {
string getARelevantTag() { result = "constructedSql" }
override string getARelevantTag() { result = "constructedSql" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SqlConstruction e, DataFlow::Node sql |
exists(location.getFile().getRelativePath()) and
@@ -146,12 +134,10 @@ class SqlConstructionTest extends InlineExpectationsTest {
}
}
class SqlExecutionTest extends InlineExpectationsTest {
SqlExecutionTest() { this = "SqlExecutionTest" }
module SqlExecutionTest implements TestSig {
string getARelevantTag() { result = "getSql" }
override string getARelevantTag() { result = "getSql" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(SqlExecution e, DataFlow::Node sql |
exists(location.getFile().getRelativePath()) and
@@ -164,12 +150,10 @@ class SqlExecutionTest extends InlineExpectationsTest {
}
}
class XPathConstructionTest extends InlineExpectationsTest {
XPathConstructionTest() { this = "XPathConstructionTest" }
module XPathConstructionTest implements TestSig {
string getARelevantTag() { result = "constructedXPath" }
override string getARelevantTag() { result = "constructedXPath" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(XML::XPathConstruction e, DataFlow::Node xpath |
exists(location.getFile().getRelativePath()) and
@@ -182,12 +166,10 @@ class XPathConstructionTest extends InlineExpectationsTest {
}
}
class XPathExecutionTest extends InlineExpectationsTest {
XPathExecutionTest() { this = "XPathExecutionTest" }
module XPathExecutionTest implements TestSig {
string getARelevantTag() { result = "getXPath" }
override string getARelevantTag() { result = "getXPath" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(XML::XPathExecution e, DataFlow::Node xpath |
exists(location.getFile().getRelativePath()) and
@@ -200,12 +182,10 @@ class XPathExecutionTest extends InlineExpectationsTest {
}
}
class EscapingTest extends InlineExpectationsTest {
EscapingTest() { this = "EscapingTest" }
module EscapingTest implements TestSig {
string getARelevantTag() { result in ["escapeInput", "escapeOutput", "escapeKind"] }
override string getARelevantTag() { result in ["escapeInput", "escapeOutput", "escapeKind"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Escaping esc |
exists(DataFlow::Node data |
@@ -232,12 +212,10 @@ class EscapingTest extends InlineExpectationsTest {
}
}
class HttpServerRouteSetupTest extends InlineExpectationsTest {
HttpServerRouteSetupTest() { this = "HttpServerRouteSetupTest" }
module HttpServerRouteSetupTest implements TestSig {
string getARelevantTag() { result = "routeSetup" }
override string getARelevantTag() { result = "routeSetup" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Http::Server::RouteSetup setup |
location = setup.getLocation() and
@@ -253,12 +231,10 @@ class HttpServerRouteSetupTest extends InlineExpectationsTest {
}
}
class HttpServerRequestHandlerTest extends InlineExpectationsTest {
HttpServerRequestHandlerTest() { this = "HttpServerRequestHandlerTest" }
module HttpServerRequestHandlerTest implements TestSig {
string getARelevantTag() { result in ["requestHandler", "routedParameter"] }
override string getARelevantTag() { result in ["requestHandler", "routedParameter"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
(
exists(Http::Server::RequestHandler handler |
@@ -330,12 +306,10 @@ class HttpServerHttpResponseTest extends InlineExpectationsTest {
}
}
class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest {
HttpServerHttpRedirectResponseTest() { this = "HttpServerHttpRedirectResponseTest" }
module HttpServerHttpRedirectResponseTest implements TestSig {
string getARelevantTag() { result in ["HttpRedirectResponse", "redirectLocation"] }
override string getARelevantTag() { result in ["HttpRedirectResponse", "redirectLocation"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
(
exists(Http::Server::HttpRedirectResponse redirect |
@@ -355,14 +329,12 @@ class HttpServerHttpRedirectResponseTest extends InlineExpectationsTest {
}
}
class HttpServerCookieWriteTest extends InlineExpectationsTest {
HttpServerCookieWriteTest() { this = "HttpServerCookieWriteTest" }
override string getARelevantTag() {
module HttpServerCookieWriteTest implements TestSig {
string getARelevantTag() {
result in ["CookieWrite", "CookieRawHeader", "CookieName", "CookieValue"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Http::Server::CookieWrite cookieWrite |
location = cookieWrite.getLocation() and
@@ -387,12 +359,10 @@ class HttpServerCookieWriteTest extends InlineExpectationsTest {
}
}
class FileSystemAccessTest extends InlineExpectationsTest {
FileSystemAccessTest() { this = "FileSystemAccessTest" }
module FileSystemAccessTest implements TestSig {
string getARelevantTag() { result = "getAPathArgument" }
override string getARelevantTag() { result = "getAPathArgument" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(FileSystemAccess a, DataFlow::Node path |
path = a.getAPathArgument() and
@@ -404,12 +374,10 @@ class FileSystemAccessTest extends InlineExpectationsTest {
}
}
class FileSystemWriteAccessTest extends InlineExpectationsTest {
FileSystemWriteAccessTest() { this = "FileSystemWriteAccessTest" }
module FileSystemWriteAccessTest implements TestSig {
string getARelevantTag() { result = "fileWriteData" }
override string getARelevantTag() { result = "fileWriteData" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(FileSystemWriteAccess write, DataFlow::Node data |
data = write.getADataNode() and
@@ -421,12 +389,10 @@ class FileSystemWriteAccessTest extends InlineExpectationsTest {
}
}
class PathNormalizationTest extends InlineExpectationsTest {
PathNormalizationTest() { this = "PathNormalizationTest" }
module PathNormalizationTest implements TestSig {
string getARelevantTag() { result = "pathNormalization" }
override string getARelevantTag() { result = "pathNormalization" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Path::PathNormalization n |
location = n.getLocation() and
@@ -437,12 +403,10 @@ class PathNormalizationTest extends InlineExpectationsTest {
}
}
class SafeAccessCheckTest extends InlineExpectationsTest {
SafeAccessCheckTest() { this = "SafeAccessCheckTest" }
module SafeAccessCheckTest implements TestSig {
string getARelevantTag() { result = "SafeAccessCheck" }
override string getARelevantTag() { result = "SafeAccessCheck" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Path::SafeAccessCheck c |
location = c.getLocation() and
@@ -453,12 +417,10 @@ class SafeAccessCheckTest extends InlineExpectationsTest {
}
}
class PublicKeyGenerationTest extends InlineExpectationsTest {
PublicKeyGenerationTest() { this = "PublicKeyGenerationTest" }
module PublicKeyGenerationTest implements TestSig {
string getARelevantTag() { result in ["PublicKeyGeneration", "keySize"] }
override string getARelevantTag() { result in ["PublicKeyGeneration", "keySize"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Cryptography::PublicKey::KeyGeneration keyGen |
location = keyGen.getLocation() and
@@ -475,17 +437,15 @@ class PublicKeyGenerationTest extends InlineExpectationsTest {
}
}
class CryptographicOperationTest extends InlineExpectationsTest {
CryptographicOperationTest() { this = "CryptographicOperationTest" }
override string getARelevantTag() {
module CryptographicOperationTest implements TestSig {
string getARelevantTag() {
result in [
"CryptographicOperation", "CryptographicOperationInput", "CryptographicOperationAlgorithm",
"CryptographicOperationBlockMode"
]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Cryptography::CryptographicOperation cryptoOperation |
location = cryptoOperation.getLocation() and
@@ -510,14 +470,12 @@ class CryptographicOperationTest extends InlineExpectationsTest {
}
}
class HttpClientRequestTest extends InlineExpectationsTest {
HttpClientRequestTest() { this = "HttpClientRequestTest" }
override string getARelevantTag() {
module HttpClientRequestTest implements TestSig {
string getARelevantTag() {
result in ["clientRequestUrlPart", "clientRequestCertValidationDisabled"]
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Http::Client::Request req, DataFlow::Node url |
url = req.getAUrlPart() and
@@ -538,12 +496,10 @@ class HttpClientRequestTest extends InlineExpectationsTest {
}
}
class CsrfProtectionSettingTest extends InlineExpectationsTest {
CsrfProtectionSettingTest() { this = "CsrfProtectionSettingTest" }
module CsrfProtectionSettingTest implements TestSig {
string getARelevantTag() { result = "CsrfProtectionSetting" }
override string getARelevantTag() { result = "CsrfProtectionSetting" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Http::Server::CsrfProtectionSetting setting |
location = setting.getLocation() and
@@ -554,12 +510,10 @@ class CsrfProtectionSettingTest extends InlineExpectationsTest {
}
}
class CsrfLocalProtectionSettingTest extends InlineExpectationsTest {
CsrfLocalProtectionSettingTest() { this = "CsrfLocalProtectionSettingTest" }
module CsrfLocalProtectionSettingTest implements TestSig {
string getARelevantTag() { result = "CsrfLocalProtection" + ["Enabled", "Disabled"] }
override string getARelevantTag() { result = "CsrfLocalProtection" + ["Enabled", "Disabled"] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(Http::Server::CsrfLocalProtectionSetting p |
location = p.getLocation() and
@@ -572,12 +526,10 @@ class CsrfLocalProtectionSettingTest extends InlineExpectationsTest {
}
}
class XmlParsingTest extends InlineExpectationsTest {
XmlParsingTest() { this = "XmlParsingTest" }
module XmlParsingTest implements TestSig {
string getARelevantTag() { result = "xmlVuln" }
override string getARelevantTag() { result = "xmlVuln" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(XML::XmlParsing parsing, XML::XmlParsingVulnerabilityKind kind |
parsing.vulnerableTo(kind) and
@@ -588,3 +540,14 @@ class XmlParsingTest extends InlineExpectationsTest {
)
}
}
import MakeTest<MergeTests5<MergeTests5<SystemCommandExecutionTest, DecodingTest, EncodingTest, LoggingTest,
CodeExecutionTest>,
MergeTests5<SqlConstructionTest, SqlExecutionTest, XPathConstructionTest, XPathExecutionTest,
EscapingTest>,
MergeTests4<HttpServerRouteSetupTest, HttpServerRequestHandlerTest,
HttpServerHttpRedirectResponseTest, HttpServerCookieWriteTest>,
MergeTests5<FileSystemAccessTest, FileSystemWriteAccessTest, PathNormalizationTest,
SafeAccessCheckTest, PublicKeyGenerationTest>,
MergeTests5<CryptographicOperationTest, HttpClientRequestTest, CsrfProtectionSettingTest,
CsrfLocalProtectionSettingTest, XmlParsingTest>>>

View File

@@ -33,10 +33,8 @@ DataFlow::Node shouldNotBeTainted() {
// this module allows the configuration to be imported in other `.ql` files without the
// top level query predicates of this file coming into scope.
module Conf {
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
override predicate isSource(DataFlow::Node source) {
module TestTaintTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asCfgNode().(NameNode).getId() in [
"TAINTED_STRING", "TAINTED_BYTES", "TAINTED_LIST", "TAINTED_DICT"
]
@@ -50,7 +48,7 @@ module Conf {
source instanceof RemoteFlowSource
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink = shouldBeTainted()
or
sink = shouldNotBeTainted()
@@ -60,49 +58,53 @@ module Conf {
import Conf
class InlineTaintTest extends InlineExpectationsTest {
InlineTaintTest() { this = "InlineTaintTest" }
module MakeInlineTaintTest<DataFlow::ConfigSig Config> {
private module Flow = TaintTracking::Global<Config>;
override string getARelevantTag() { result = "tainted" }
private module InlineTaintTest implements TestSig {
string getARelevantTag() { result = "tainted" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlow::Node sink |
Flow::flowTo(sink) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
value = "" and
tag = "tainted"
)
}
}
import MakeTest<InlineTaintTest>
query predicate argumentToEnsureNotTaintedNotMarkedAsSpurious(
Location location, string error, string element
) {
error = "ERROR, you should add `SPURIOUS:` to this annotation" and
location = shouldNotBeTainted().getLocation() and
InlineTaintTest::hasActualResult(location, element, "tainted", _) and
exists(GoodTestExpectation good, ActualTestResult actualResult |
good.matchesActualResult(actualResult) and
actualResult.getLocation() = location and
actualResult.toString() = element
)
}
query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing(
Location location, string error, string element
) {
error = "ERROR, you should add `# $ MISSING: tainted` annotation" and
exists(DataFlow::Node sink |
any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and
location = sink.getLocation() and
sink = shouldBeTainted() and
element = prettyExpr(sink.asExpr()) and
value = "" and
tag = "tainted"
not Flow::flowTo(sink) and
location = sink.getLocation() and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "tainted" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
)
)
}
}
query predicate argumentToEnsureNotTaintedNotMarkedAsSpurious(
Location location, string error, string element
) {
error = "ERROR, you should add `SPURIOUS:` to this annotation" and
location = shouldNotBeTainted().getLocation() and
any(InlineTaintTest test).hasActualResult(location, element, "tainted", _) and
exists(GoodExpectation good, ActualResult actualResult |
good.matchesActualResult(actualResult) and
actualResult.getLocation() = location and
actualResult.toString() = element
)
}
query predicate untaintedArgumentToEnsureTaintedNotMarkedAsMissing(
Location location, string error, string element
) {
error = "ERROR, you should add `# $ MISSING: tainted` annotation" and
exists(DataFlow::Node sink |
sink = shouldBeTainted() and
element = prettyExpr(sink.asExpr()) and
not any(TestTaintTrackingConfiguration config).hasFlow(_, sink) and
location = sink.getLocation() and
not exists(FalseNegativeExpectation missingResult |
missingResult.getTag() = "tainted" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
)
)
}

View File

@@ -7,16 +7,14 @@ private import semmle.python.Frameworks
// this import needs to be public to get the query predicates propagated to the actual test files
import TestUtilities.InlineExpectationsTest
class MadSinkTest extends InlineExpectationsTest {
MadSinkTest() { this = "MadSinkTest" }
override string getARelevantTag() {
module MadSinkTest implements TestSig {
string getARelevantTag() {
exists(string kind | exists(ModelOutput::getASinkNode(kind)) |
result = "mad-sink[" + kind + "]"
)
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlow::Node sink, string kind |
sink = ModelOutput::getASinkNode(kind).asSink() and
@@ -28,14 +26,12 @@ class MadSinkTest extends InlineExpectationsTest {
}
}
class MadSourceTest extends InlineExpectationsTest {
MadSourceTest() { this = "MadSourceTest" }
override string getARelevantTag() {
module MadSourceTest implements TestSig {
string getARelevantTag() {
exists(string kind | exists(ModelOutput::getASourceNode(kind)) | result = "mad-source__" + kind)
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(DataFlow::Node source, string kind |
source = ModelOutput::getASourceNode(kind).asSource() and
@@ -46,3 +42,5 @@ class MadSourceTest extends InlineExpectationsTest {
)
}
}
import MakeTest<MergeTests<MadSinkTest, MadSourceTest>>

View File

@@ -13,11 +13,9 @@ import semmle.python.dataflow.new.TaintTracking
import experimental.meta.InlineTaintTest::Conf
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
any(TestTaintTrackingConfiguration c).isSource(source)
}
predicate isSource(DataFlow::Node source) { TestTaintTrackingConfig::isSource(source) }
predicate isSink(DataFlow::Node source) { any(TestTaintTrackingConfiguration c).isSink(source) }
predicate isSink(DataFlow::Node source) { TestTaintTrackingConfig::isSink(source) }
}
module Flows = TaintTracking::Global<Config>;

View File

@@ -12,9 +12,9 @@ import semmle.python.dataflow.new.DataFlow
import experimental.dataflow.testConfig
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { any(TestConfiguration c).isSource(source) }
predicate isSource(DataFlow::Node source) { TestConfig::isSource(source) }
predicate isSink(DataFlow::Node source) { any(TestConfiguration c).isSink(source) }
predicate isSink(DataFlow::Node source) { TestConfig::isSink(source) }
}
module Flows = DataFlow::Global<Config>;

View File

@@ -1,7 +1,8 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
| taint_test.py:48:9:48:29 | taint_test.py:48 | ERROR, you should add `SPURIOUS:` to this annotation | should_not_be_tainted |
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
| taint_test.py:32:9:32:25 | taint_test.py:32 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
| taint_test.py:37:24:37:40 | taint_test.py:37 | ERROR, you should add `# $ MISSING: tainted` annotation | should_be_tainted |
failures
testFailures
| taint_test.py:41:20:41:21 | ts | Fixed missing result:tainted= |

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,2 +1,3 @@
missingAnnotationOnSink
failures
testFailures

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1,7 +1,11 @@
import experimental.meta.InlineTaintTest
import semmle.python.Concepts
class HtmlSpecialization extends TestTaintTrackingConfiguration {
module HtmlSpecializationConfig implements DataFlow::ConfigSig {
predicate isSource = TestTaintTrackingConfig::isSource/1;
predicate isSink = TestTaintTrackingConfig::isSink/1;
// TODO: For now, since there is not an `isSanitizingStep` member-predicate part of a
// `TaintTracking::Configuration`, we use treat the output is a taint-sanitizer. This
// is slightly imprecise, which you can see in the `m_unsafe + SAFE` test-case in
@@ -9,5 +13,7 @@ class HtmlSpecialization extends TestTaintTrackingConfiguration {
//
// However, it is better than `getAnInput()`. Due to use-use flow, that would remove
// the taint-flow to `SINK()` in `some_escape(tainted); SINK(tainted)`.
override predicate isSanitizer(DataFlow::Node node) { node = any(HtmlEscaping esc).getOutput() }
predicate isBarrier(DataFlow::Node node) { node = any(HtmlEscaping esc).getOutput() }
}
import MakeInlineTaintTest<HtmlSpecializationConfig>

View File

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

View File

@@ -1,3 +1,4 @@
failures
argumentToEnsureNotTaintedNotMarkedAsSpurious
untaintedArgumentToEnsureTaintedNotMarkedAsMissing
failures
testFailures

View File

@@ -1 +1,2 @@
import experimental.meta.InlineTaintTest
import MakeInlineTaintTest<TestTaintTrackingConfig>

Some files were not shown because too many files have changed in this diff Show More