Merge pull request #14983 from aschackmull/dataflow/deprecate-old-api

Data Flow: Deprecate old data flow api.
This commit is contained in:
Anders Schack-Mulligen
2023-12-08 14:27:25 +01:00
committed by GitHub
79 changed files with 785 additions and 738 deletions

View File

@@ -104,9 +104,9 @@ module FromTaintTrackingStateConfig<DataFlow::StateConfigSig C> {
import MakeQueryTest<Impl>
}
signature class LegacyConfiguration extends DataFlow::Configuration;
deprecated signature class LegacyConfiguration extends DataFlow::Configuration;
module FromLegacyConfiguration<LegacyConfiguration C> {
deprecated module FromLegacyConfiguration<LegacyConfiguration C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { any(C c).isSink(sink) or any(C c).isSink(sink, _) }

View File

@@ -4,10 +4,10 @@ import semmle.python.dataflow.new.DataFlow
* A configuration to find all flows.
* To be used on tiny programs.
*/
class AllFlowsConfig extends DataFlow::Configuration {
AllFlowsConfig() { this = "AllFlowsConfig" }
module AllFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { any() }
override predicate isSource(DataFlow::Node node) { any() }
override predicate isSink(DataFlow::Node node) { any() }
predicate isSink(DataFlow::Node node) { any() }
}
module AllFlowsFlow = DataFlow::Global<AllFlowsConfig>;

View File

@@ -2,7 +2,7 @@ import experimental.dataflow.callGraphConfig
from DataFlow::Node source, DataFlow::Node sink
where
exists(CallGraphConfig cfg | cfg.hasFlow(source, sink)) and
CallGraphFlow::flow(source, sink) and
exists(source.getLocation().getFile().getRelativePath()) and
exists(sink.getLocation().getFile().getRelativePath())
select source, sink

View File

@@ -2,6 +2,6 @@ import experimental.dataflow.callGraphConfig
from DataFlow::Node sink
where
exists(CallGraphConfig cfg | cfg.isSink(sink)) and
CallGraphConfig::isSink(sink) and
exists(sink.getLocation().getFile().getRelativePath())
select sink

View File

@@ -2,6 +2,6 @@ import experimental.dataflow.callGraphConfig
from DataFlow::Node source
where
exists(CallGraphConfig cfg | cfg.isSource(source)) and
CallGraphConfig::isSource(source) and
exists(source.getLocation().getFile().getRelativePath())
select source

View File

@@ -3,7 +3,7 @@ import allFlowsConfig
from DataFlow::Node source, DataFlow::Node sink
where
source != sink and
exists(AllFlowsConfig cfg | cfg.hasFlow(source, sink)) and
AllFlowsFlow::flow(source, sink) and
exists(source.getLocation().getFile().getRelativePath()) and
exists(sink.getLocation().getFile().getRelativePath())
select source, sink

View File

@@ -1,6 +1,6 @@
import allFlowsConfig
from DataFlow::PathNode fromNode, DataFlow::PathNode toNode
from AllFlowsFlow::PathNode fromNode, AllFlowsFlow::PathNode toNode
where
toNode = fromNode.getASuccessor() and
exists(fromNode.getNode().getLocation().getFile().getRelativePath()) and

View File

@@ -3,7 +3,7 @@ import maximalFlowsConfig
from DataFlow::Node source, DataFlow::Node sink
where
source != sink and
exists(MaximalFlowsConfig cfg | cfg.hasFlow(source, sink)) and
MaximalFlowsFlow::flow(source, sink) and
exists(source.getLocation().getFile().getRelativePath()) and
exists(sink.getLocation().getFile().getRelativePath())
select source, sink

View File

@@ -6,18 +6,18 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
* A configuration to find all "maximal" flows.
* To be used on small programs.
*/
class MaximalFlowsConfig extends DataFlow::Configuration {
MaximalFlowsConfig() { this = "AllFlowsConfig" }
override predicate isSource(DataFlow::Node node) {
module MaximalFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node instanceof DataFlow::ParameterNode
or
node instanceof DataFlow::LocalSourceNode
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
node instanceof DataFlowPrivate::ReturnNode
or
not DataFlowPrivate::LocalFlow::localFlowStep(node, _)
}
}
module MaximalFlowsFlow = DataFlow::Global<MaximalFlowsConfig>;

View File

@@ -2,6 +2,6 @@ import allFlowsConfig
from DataFlow::Node sink
where
exists(AllFlowsConfig cfg | cfg.isSink(sink)) and
AllFlowsConfig::isSink(sink) and
exists(sink.getLocation().getFile().getRelativePath())
select sink

View File

@@ -2,6 +2,6 @@ import allFlowsConfig
from DataFlow::Node source
where
exists(AllFlowsConfig cfg | cfg.isSource(source)) and
AllFlowsConfig::isSource(source) and
exists(source.getLocation().getFile().getRelativePath())
select source

View File

@@ -5,18 +5,18 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
/**
* A configuration to find the call graph edges.
*/
class CallGraphConfig extends DataFlow::Configuration {
CallGraphConfig() { this = "CallGraphConfig" }
override predicate isSource(DataFlow::Node node) {
module CallGraphConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node instanceof DataFlowPrivate::ReturnNode
or
node instanceof DataFlow::ArgumentNode
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
node instanceof DataFlowPrivate::OutNode
or
node instanceof DataFlow::ParameterNode
}
}
module CallGraphFlow = DataFlow::Global<CallGraphConfig>;

View File

@@ -10,13 +10,11 @@ module Argument1RoutingTest implements RoutingTestSig {
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink, Argument arg) {
(
exists(Argument1ExtraRoutingConfig cfg | cfg.hasFlow(source, sink))
Argument1ExtraRoutingFlow::flow(source, sink)
or
exists(ArgumentRoutingConfig cfg |
cfg.hasFlow(source, sink) and
cfg.isArgSource(source, 1) and
cfg.isGoodSink(sink, 1)
)
ArgumentRoutingFlow::flow(source, sink) and
ArgumentRoutingConfig::isArgSource(source, 1) and
ArgumentRoutingConfig::isGoodSink(sink, 1)
) and
exists(arg)
}
@@ -26,32 +24,28 @@ class ArgNumber extends int {
ArgNumber() { this in [1 .. 7] }
}
class ArgumentRoutingConfig extends DataFlow::Configuration {
ArgumentRoutingConfig() { this = "ArgumentRoutingConfig" }
predicate isArgSource(DataFlow::Node node, ArgNumber argNumber) {
module ArgumentRoutingConfig implements DataFlow::ConfigSig {
additional predicate isArgSource(DataFlow::Node node, ArgNumber argNumber) {
node.(DataFlow::CfgNode).getNode().(NameNode).getId() = "arg" + argNumber
}
override predicate isSource(DataFlow::Node node) { this.isArgSource(node, _) }
predicate isSource(DataFlow::Node node) { isArgSource(node, _) }
predicate isGoodSink(DataFlow::Node node, ArgNumber argNumber) {
additional predicate isGoodSink(DataFlow::Node node, ArgNumber argNumber) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK" + argNumber and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
predicate isBadSink(DataFlow::Node node, ArgNumber argNumber) {
additional predicate isBadSink(DataFlow::Node node, ArgNumber argNumber) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK" + argNumber + "_F" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
)
}
override predicate isSink(DataFlow::Node node) {
this.isGoodSink(node, _) or this.isBadSink(node, _)
}
predicate isSink(DataFlow::Node node) { isGoodSink(node, _) or isBadSink(node, _) }
/**
* We want to be able to use `arg` in a sequence of calls such as `func(kw=arg); ... ; func(arg)`.
@@ -59,13 +53,13 @@ class ArgumentRoutingConfig extends DataFlow::Configuration {
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
class Argument1ExtraRoutingConfig extends DataFlow::Configuration {
Argument1ExtraRoutingConfig() { this = "Argument1ExtraRoutingConfig" }
module ArgumentRoutingFlow = DataFlow::Global<ArgumentRoutingConfig>;
override predicate isSource(DataFlow::Node node) {
module Argument1ExtraRoutingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
exists(AssignmentDefinition def, DataFlow::CallCfgNode call |
def.getDefiningNode() = node.(DataFlow::CfgNode).getNode() and
def.getValue() = call.getNode() and
@@ -74,7 +68,7 @@ class Argument1ExtraRoutingConfig extends DataFlow::Configuration {
node.(DataFlow::CfgNode).getNode().(NameNode).getId().matches("with\\_%")
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK1" and
node.(DataFlow::CfgNode).getNode() = call.getAnArg()
@@ -87,20 +81,20 @@ class Argument1ExtraRoutingConfig extends DataFlow::Configuration {
* making it seem like we handle all cases even if we only handle the last one.
* We make the test honest by preventing flow into source nodes.
*/
override predicate isBarrierIn(DataFlow::Node node) { this.isSource(node) }
predicate isBarrierIn(DataFlow::Node node) { isSource(node) }
}
module Argument1ExtraRoutingFlow = DataFlow::Global<Argument1ExtraRoutingConfig>;
module RestArgumentRoutingTest implements RoutingTestSig {
class Argument = ArgNumber;
string flowTag(Argument arg) { result = "arg" + arg }
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink, Argument arg) {
exists(ArgumentRoutingConfig cfg |
cfg.hasFlow(source, sink) and
cfg.isArgSource(source, arg) and
cfg.isGoodSink(sink, arg)
) and
ArgumentRoutingFlow::flow(source, sink) and
ArgumentRoutingConfig::isArgSource(source, arg) and
ArgumentRoutingConfig::isGoodSink(sink, arg) and
arg > 1
}
}
@@ -112,11 +106,9 @@ module BadArgumentRoutingTestSinkF implements RoutingTestSig {
string flowTag(Argument arg) { result = "bad" + arg }
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink, Argument arg) {
exists(ArgumentRoutingConfig cfg |
cfg.hasFlow(source, sink) and
cfg.isArgSource(source, arg) and
cfg.isBadSink(sink, arg)
)
ArgumentRoutingFlow::flow(source, sink) and
ArgumentRoutingConfig::isArgSource(source, arg) and
ArgumentRoutingConfig::isBadSink(sink, arg)
}
}
@@ -127,14 +119,12 @@ module BadArgumentRoutingTestWrongSink implements RoutingTestSig {
string flowTag(Argument arg) { result = "bad" + arg }
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink, Argument arg) {
exists(ArgumentRoutingConfig cfg |
cfg.hasFlow(source, sink) and
cfg.isArgSource(source, any(ArgNumber i | not i = arg)) and
(
cfg.isGoodSink(sink, arg)
or
cfg.isBadSink(sink, arg)
)
ArgumentRoutingFlow::flow(source, sink) and
ArgumentRoutingConfig::isArgSource(source, any(ArgNumber i | not i = arg)) and
(
ArgumentRoutingConfig::isGoodSink(sink, arg)
or
ArgumentRoutingConfig::isBadSink(sink, arg)
)
}
}

View File

@@ -4,16 +4,16 @@ import semmle.python.dataflow.new.DataFlow
* A configuration to find all flows.
* To be used on tiny programs.
*/
class AllFlowsConfig extends DataFlow::Configuration {
AllFlowsConfig() { this = "AllFlowsConfig" }
module AllFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { any() }
override predicate isSource(DataFlow::Node node) { any() }
override predicate isSink(DataFlow::Node node) { any() }
predicate isSink(DataFlow::Node node) { any() }
}
module AllFlowsFlow = DataFlow::Global<AllFlowsConfig>;
from DataFlow::CfgNode source, DataFlow::CfgNode sink
where
source != sink and
exists(AllFlowsConfig cfg | cfg.hasFlow(source, sink))
AllFlowsFlow::flow(source, sink)
select source, sink

View File

@@ -10,14 +10,10 @@
import python
import semmle.python.dataflow.new.DataFlow
class CustomTestConfiguration extends DataFlow::Configuration {
CustomTestConfiguration() { this = "CustomTestConfiguration" }
module CustomTestConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node.asCfgNode().(NameNode).getId() = "CUSTOM_SOURCE" }
override predicate isSource(DataFlow::Node node) {
node.asCfgNode().(NameNode).getId() = "CUSTOM_SOURCE"
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(CallNode call |
call.getFunction().(NameNode).getId() in ["CUSTOM_SINK", "CUSTOM_SINK_F"] and
node.asCfgNode() = call.getAnArg()
@@ -25,6 +21,8 @@ class CustomTestConfiguration extends DataFlow::Configuration {
}
}
module CustomTestFlow = DataFlow::Global<CustomTestConfig>;
from DataFlow::Node source, DataFlow::Node sink
where exists(CustomTestConfiguration cfg | cfg.hasFlow(source, sink))
where CustomTestFlow::flow(source, sink)
select source, sink

View File

@@ -20,7 +20,7 @@ module SensitiveDataSourcesTest implements TestSig {
tag = "SensitiveDataSource"
or
exists(DataFlow::Node use |
any(SensitiveUseConfiguration config).hasFlow(source, use) and
SensitiveUseFlow::flow(source, use) and
location = use.getLocation() and
element = use.toString() and
value = source.getClassification() and
@@ -32,19 +32,17 @@ module SensitiveDataSourcesTest implements TestSig {
import MakeTest<SensitiveDataSourcesTest>
class SensitiveUseConfiguration extends TaintTracking::Configuration {
SensitiveUseConfiguration() { this = "SensitiveUseConfiguration" }
module SensitiveUseConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { node instanceof SensitiveDataSource }
override predicate isSource(DataFlow::Node node) { node instanceof SensitiveDataSource }
predicate isSink(DataFlow::Node node) { node = API::builtin("print").getACall().getArg(_) }
override predicate isSink(DataFlow::Node node) {
node = API::builtin("print").getACall().getArg(_)
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
sensitiveDataExtraStepForCalls(node1, node2)
}
}
module SensitiveUseFlow = TaintTracking::Global<SensitiveUseConfig>;
// import DataFlow::PathGraph
// from SensitiveUseConfiguration cfg, DataFlow::PathNode source, DataFlow::PathNode sink
// where cfg.hasFlowPath(source, sink)

View File

@@ -3,10 +3,8 @@ import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.internal.PrintNode
class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
TestTaintTrackingConfiguration() { this = "TestTaintTrackingConfiguration" }
override predicate isSource(DataFlow::Node source) {
module TestTaintTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
// Standard sources
source.(DataFlow::CfgNode).getNode().(NameNode).getId() in [
"TAINTED_STRING", "TAINTED_BYTES", "TAINTED_LIST", "TAINTED_DICT"
@@ -19,7 +17,7 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
)
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(CallNode call |
call.getFunction().(NameNode).getId() in ["ensure_tainted", "ensure_not_tainted"] and
sink.(DataFlow::CfgNode).getNode() = call.getAnArg()
@@ -27,6 +25,8 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
module TestTaintTrackingFlow = DataFlow::Global<TestTaintTrackingConfig>;
query predicate test_taint(string arg_location, string test_res, string scope_name, string repr) {
exists(Call call, Expr arg, boolean expected_taint, boolean has_taint |
// only consider files that are extracted as part of the test
@@ -42,9 +42,9 @@ query predicate test_taint(string arg_location, string test_res, string scope_na
(
// TODO: Replace with `hasFlowToExpr` once that is working
if
exists(TaintTracking::Configuration c |
c.hasFlowTo(any(DataFlow::Node n | n.(DataFlow::CfgNode).getNode() = arg.getAFlowNode()))
)
TestTaintTrackingFlow::flowTo(any(DataFlow::Node n |
n.(DataFlow::CfgNode).getNode() = arg.getAFlowNode()
))
then has_taint = true
else has_taint = false
) and

View File

@@ -2,14 +2,12 @@ import python
import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.DataFlow
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.(DataFlow::CfgNode).getNode().(NameNode).getId() = "SOURCE"
}
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "SINK" and
sink.(DataFlow::CfgNode).getNode() = call.getAnArg()
@@ -17,6 +15,8 @@ class TestTaintTrackingConfiguration extends TaintTracking::Configuration {
}
}
from TestTaintTrackingConfiguration config, DataFlow::Node source, DataFlow::Node sink
where config.hasFlow(source, sink)
module TestTaintTrackingFlow = DataFlow::Global<TestTaintTrackingConfig>;
from DataFlow::Node source, DataFlow::Node sink
where TestTaintTrackingFlow::flow(source, sink)
select source, sink

View File

@@ -58,27 +58,27 @@ private class VersionGuardedNode extends DataFlow::Node {
int getVersion() { result = version }
}
private class ImportConfiguration extends DataFlow::Configuration {
ImportConfiguration() { this = "ImportConfiguration" }
module ImportConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof SourceString }
override predicate isSource(DataFlow::Node source) { source instanceof SourceString }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
sink = API::moduleImport("trace").getMember("check").getACall().getArg(1)
}
override predicate isBarrier(DataFlow::Node node) {
predicate isBarrier(DataFlow::Node node) {
exists(DataFlow::MethodCallNode call | call.calls(node, "block_flow"))
}
}
module ImportFlow = DataFlow::Global<ImportConfig>;
module ResolutionTest implements TestSig {
string getARelevantTag() { result = "prints" }
predicate hasActualResult(Location location, string element, string tag, string value) {
(
exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config |
config.hasFlowPath(source, sink) and
exists(ImportFlow::PathNode source, ImportFlow::PathNode sink |
ImportFlow::flowPath(source, sink) and
not sink.getNode() instanceof VersionGuardedNode and
tag = "prints" and
location = sink.getNode().getLocation() and
@@ -108,8 +108,8 @@ module VersionSpecificResolutionTest implements TestSig {
predicate hasActualResult(Location location, string element, string tag, string value) {
(
exists(DataFlow::PathNode source, DataFlow::PathNode sink, ImportConfiguration config |
config.hasFlowPath(source, sink) and
exists(ImportFlow::PathNode source, ImportFlow::PathNode sink |
ImportFlow::flowPath(source, sink) and
tag = getTagForVersion(sink.getNode().(VersionGuardedNode).getVersion()) and
location = sink.getNode().getLocation() and
value = source.getNode().(SourceString).getContents() and

View File

@@ -10,26 +10,18 @@ predicate pointsToOrigin(DataFlow::CfgNode pointer, DataFlow::CfgNode origin) {
origin.getNode() = pointer.getNode().pointsTo().getOrigin()
}
class PointsToConfiguration extends DataFlow::Configuration {
PointsToConfiguration() { this = "PointsToConfiguration" }
module PointsToConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) { pointsToOrigin(_, node) }
override predicate isSource(DataFlow::Node node) { pointsToOrigin(_, node) }
override predicate isSink(DataFlow::Node node) { pointsToOrigin(node, _) }
predicate isSink(DataFlow::Node node) { pointsToOrigin(node, _) }
}
predicate hasFlow(DataFlow::Node origin, DataFlow::Node pointer) {
exists(PointsToConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink |
source.getNode() = origin and
sink.getNode() = pointer and
config.hasFlowPath(source, sink)
)
}
module PointsToFlow = DataFlow::Global<PointsToConfig>;
from DataFlow::Node pointer, DataFlow::Node origin
where
exists(pointer.getLocation().getFile().getRelativePath()) and
exists(origin.getLocation().getFile().getRelativePath()) and
pointsToOrigin(pointer, origin) and
not hasFlow(origin, pointer)
not PointsToFlow::flow(origin, pointer)
select origin, pointer

View File

@@ -5,20 +5,18 @@ import semmle.python.dataflow.new.TaintTracking
import semmle.python.dataflow.new.DataFlow
private import semmle.python.ApiGraphs
class BasicTaintTracking extends TaintTracking::Configuration {
BasicTaintTracking() { this = "BasicTaintTracking" }
override predicate isSource(DataFlow::Node source) {
module BasicTaintTrackingConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source = ModelOutput::getASourceNode("test-source").asSource()
}
override predicate isSink(DataFlow::Node sink) {
sink = ModelOutput::getASinkNode("test-sink").asSink()
}
predicate isSink(DataFlow::Node sink) { sink = ModelOutput::getASinkNode("test-sink").asSink() }
}
module TestTaintTrackingFlow = TaintTracking::Global<BasicTaintTrackingConfig>;
query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) {
any(BasicTaintTracking tr).hasFlow(source, sink)
TestTaintTrackingFlow::flow(source, sink)
}
query predicate isSink(DataFlow::Node node, string kind) {

View File

@@ -5,7 +5,7 @@
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.TaintTracking
import DataFlow::PathGraph
import SharedFlow::PathGraph
import SharedCode
class MyClassGetValueAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
@@ -18,7 +18,7 @@ class MyClassGetValueAdditionalTaintStep extends TaintTracking::AdditionalTaintS
}
}
from SharedConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
from SharedFlow::PathNode source, SharedFlow::PathNode sink
where SharedFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"test flow (naive): " + source.getNode().asCfgNode().getScope().getName()

View File

@@ -5,7 +5,7 @@
private import python
private import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.TaintTracking
import DataFlow::PathGraph
import SharedFlow::PathGraph
import SharedCode
class MyClassGetValueAdditionalTaintStep extends TaintTracking::AdditionalTaintStep {
@@ -20,7 +20,7 @@ class MyClassGetValueAdditionalTaintStep extends TaintTracking::AdditionalTaintS
}
}
from SharedConfig config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
from SharedFlow::PathNode source, SharedFlow::PathNode sink
where SharedFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"test flow (proper): " + source.getNode().asCfgNode().getScope().getName()

View File

@@ -22,15 +22,15 @@ class SourceCall extends DataFlow::Node, MyClass {
SourceCall() { this.asCfgNode().(CallNode).getFunction().(NameNode).getId() = "source" }
}
class SharedConfig extends TaintTracking::Configuration {
SharedConfig() { this = "SharedConfig" }
private module SharedConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof SourceCall }
override predicate isSource(DataFlow::Node source) { source instanceof SourceCall }
override predicate isSink(DataFlow::Node sink) {
predicate isSink(DataFlow::Node sink) {
exists(CallNode call |
call.getFunction().(NameNode).getId() = "sink" and
call.getArg(0) = sink.asCfgNode()
)
}
}
module SharedFlow = TaintTracking::Global<SharedConfig>;