From d879a89c503af96782bf86b17899f1d9153b64ed Mon Sep 17 00:00:00 2001 From: Xavier Pinho Date: Fri, 18 Oct 2024 11:47:25 +0100 Subject: [PATCH] [dataflowengineoss] Fix PassThroughMapping criteria for same-call named arguments (#5003) * [dataflowengineoss] Fix PassThroughMapping criteria for named arguments * sort result for testing purposes --- .../nodemethods/ExpressionMethods.scala | 4 +- .../pysrc2cpg/dataflow/DataFlowTests.scala | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/language/nodemethods/ExpressionMethods.scala b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/language/nodemethods/ExpressionMethods.scala index 7480b0c0951f..362cefee6d46 100644 --- a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/language/nodemethods/ExpressionMethods.scala +++ b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/language/nodemethods/ExpressionMethods.scala @@ -64,8 +64,8 @@ class ExpressionMethods[NodeType <: Expression](val node: NodeType) extends AnyV srcIndex == node.argumentIndex && dstName == tgt.argumentName.get case FlowMapping(ParameterNode(srcIndex, _), ParameterNode(dstIndex, _)) => srcIndex == node.argumentIndex && dstIndex == tgt.argumentIndex - case PassThroughMapping if tgt.argumentIndex == node.argumentIndex || tgt.argumentIndex == -1 => true - case _ => false + case PassThroughMapping => node.argumentIndex == tgt.argumentIndex && node.argumentName == tgt.argumentName + case _ => false } } } diff --git a/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/dataflow/DataFlowTests.scala b/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/dataflow/DataFlowTests.scala index 15a47446ed25..66afb379fa0b 100644 --- a/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/dataflow/DataFlowTests.scala +++ b/joern-cli/frontends/pysrc2cpg/src/test/scala/io/joern/pysrc2cpg/dataflow/DataFlowTests.scala @@ -993,6 +993,46 @@ class NoCrossTaintDataFlowTest1 val sink = cpg.call("baz").argument.argumentIndex(1) sink.reachableByFlows(source).map(flowToResultPairs) shouldBe empty } + + "NoCrossTaintSemantics prevents cross-tainting same-call named-arguments to external method calls" in { + val cpg = code(""" + |import bar + |a = 1 + |b = 2 + |bar.foo(X=a, Y=b) + |""".stripMargin) + val source = cpg.literal("1") + val sink = cpg.call("foo").argument.argumentName("Y") + sink.reachableByFlows(source) shouldBe empty + } + + "NoCrossTaintSemantics prevents cross-tainting same-call arguments to external method calls" in { + val cpg = code(""" + |import bar + |a = 1 + |b = 2 + |bar.foo(A=b, a) + |""".stripMargin) + val source = cpg.literal("1") + val sink = cpg.call("foo").argument.argumentName("A") + sink.reachableByFlows(source) shouldBe empty + } + + "NoCrossTaintSemantics taints return values" in { + val cpg = code(""" + |import bar + |a = 1 + |b = 2 + |c = bar.foo(X=a, b) + |print(c) + |""".stripMargin) + val source = cpg.literal.lineNumber(3, 4) + val sink = cpg.call("print").argument + sink.reachableByFlows(source).map(flowToResultPairs).sorted shouldBe List( + List(("a = 1", 3), ("bar.foo(b, X = a)", 5), ("c = bar.foo(b, X = a)", 5), ("print(c)", 6)), + List(("b = 2", 4), ("bar.foo(b, X = a)", 5), ("c = bar.foo(b, X = a)", 5), ("print(c)", 6)) + ) + } } class NoCrossTaintDataFlowTest2