Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Java] The reachableByFlows function is unable to function properly when encountering a sink point with a void return type. #4414

Open
wooyune1 opened this issue Apr 2, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@wooyune1
Copy link

wooyune1 commented Apr 2, 2024

Describe the bug
When a sink point is a function that doesn't provide any return information, it's not feasible to derive the path leading to the vulnerability.

To Reproduce
When the sink has a return value

public class A {
    public static void main(String[] args) {
        String s = source();
        sink(s);
    }
    public static String source() {
        return "abc";
    }
    public static String sink(String s) {
        String temp = s;
        return s;
    }
}

When the sink doesn't have a return value

public class A {
    public static void main(String[] args) {
        String s = source();
        sink(s);
    }
    public static String source() {
        return "abc";
    }
    public static void sink(String s) {
        String temp = s;
    }
}

My code

  def main(args: Array[String]): Unit = {
    implicit val dataFlowContext: EngineContext = EngineContext()
    val config = Config()
      .withInputPath("src/test/resources/")
    //            .withOutputPath("cpg/")
    implicit val cpg: Cpg = new JavaSrc2Cpg().createCpg(config).get

    runDataFlowLayer(cpg)

    val source = cpg.call.name("source")
    val sink = cpg.call.name("sink")

    val paths = sink.reachableByFlows(source)
    paths.p.foreach ((path) => {
      println(path)
    })

  }

  def runDataFlowLayer(cpg: Cpg): Unit = {
    val context = new LayerCreatorContext(cpg)

    new Base().run(context)
    new TypeRelations().run(context)
    new ControlFlow().run(context)
    new CallGraph().run(context)

    val options = new OssDataFlowOptions(4000)
    new dataflows.OssDataFlow(options).run(context)
  }

Expected behavior
I expected that both Java code snippets would be able to find a path from source to sink, but in reality, only the one where the sink function has a return value can successfully identify such a path.

Screenshots
The path found by the code for the sink function with a return value.
image

Desktop (please complete the following information):

  • Joern Version : v2.0.311
  • Java version : 17
@wooyune1 wooyune1 added the bug Something isn't working label Apr 2, 2024
@maltek
Copy link
Contributor

maltek commented Apr 2, 2024

In dataflow queries, calls stand for the value returned by these calls. If you are interested in something other than that return value, you must adjust the sink of query. E.g. use def sink = cpg.method.name("sink").parameter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants