joern icon indicating copy to clipboard operation
joern copied to clipboard

[dataflowengineoss] Over-tainting inlined literals

Open xavierpinho opened this issue 8 months ago • 0 comments

Setup

Tested on Joern 2.0.405

Compare Scenario 1 with Scenario 3 and Scenario 2 with Scenario 4 below. Even though these pairs of samples are equivalent, their results are different: in the failing samples, the literal 20 is tainting print, and the sole difference is that we inline the literal.

If we hadn't specified FlowSemantics for foo, the results would coincide, but we can also note that they work as expected when the literal is not inlined, i.e. FlowSemantics are respected when the literal is not inlined.

Scenario 1 ✅

"scenario 1" in {
  val cpg = code(
    """
      |from helpers import foo
      |a = 20
      |print(foo(a))
      |""".stripMargin)
    .withExtraFlows(
      List(FlowSemantic("helpers.py:<module>.foo", List(FlowMapping(0,0))))
  )
  def source = cpg.literal("20")
  def sink = cpg.call("print").argument(1)
  def flows = sink.reachableByFlows(source)
  flows shouldBe empty
}

Scenario 2 ✅

"scenario 2" in {
  val cpg = code(
    """
      |def foo(x):
      |   return x
      |
      |a = 20
      |print(foo(a))
      |""".stripMargin)
    .withExtraFlows(List(
      FlowSemantic("Test0.py:<module>.foo", List(FlowMapping(0,0)))
    ))

  def source = cpg.literal("20")
  def sink = cpg.call("print").argument(1)
  def flows = sink.reachableByFlows(source)
  flows shouldBe empty
}

Scenario 3 ❌

"scenario 3" in {
  val cpg = code(
    """
      |from helpers import foo
      |print(foo(20))
      |""".stripMargin)
    .withExtraFlows(
      List(FlowSemantic("helpers.py:<module>.foo", List(FlowMapping(0,0))))
    )

  def source = cpg.literal("20")
  def sink = cpg.call("print").argument(1)
  def flows = sink.reachableByFlows(source)
  flows shouldBe empty
}

Scenario 4 ❌

"scenario 4" in {
  val cpg = code(
    """
      |def foo(x):
      |   return x
      |
      |print(foo(20))
      |""".stripMargin)
    .withExtraFlows(List(
      FlowSemantic("Test0.py:<module>.foo", List(FlowMapping(0,0)))
    ))

  def source = cpg.literal("20")
  def sink = cpg.call("print").argument(1)
  def flows = sink.reachableByFlows(source)
  flows shouldBe empty
}

xavierpinho avatar Jun 13 '24 13:06 xavierpinho