pascal-lab/Tai-e

How to configure Taint Transfer for such case?

Closed this issue · 7 comments

Description

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class TestTaiE {
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8080);
        Socket socket = server.accept();
        BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = is.readLine();
        sink(line);
    }


    public static void sink(String s2) throws IOException {
        Runtime.getRuntime().exec(s2);
    }
}
sources:
  - { kind: call, method: "<java.net.Socket: java.io.InputStream getInputStream()>", index: result}
sinks:
  - { method: "<java.lang.Runtime: java.lang.Process exec(java.lang.String)>", index: 0 }

Hi @75ACOL,

Thank you for bringing this issue to our attention. To help us address your concern more effectively, we would greatly appreciate additional details. Specifically, could you provide:

  • Expected vs. Actual Behavior: Describe what you expected to happen and what actually occurred.
  • Steps to Reproduce: Can you outline the steps you took that led to the issue? This will help us replicate the problem on our end.
  • Your Attempts to Resolve the Issue: Detail any steps you've already taken to troubleshoot or resolve the issue.
  • Runtime Environment: Include details about your operating system, and any other relevant environment specifics.
  • Tai-e Version: Please specify the version of our project you are using.

If you're unsure about any of these details, feel free to ask for guidance. We're here to assist you. For your convenience, you can also use our issue templates, which help in organizing and submitting the required information efficiently.

We appreciate your contribution to our project and look forward to your response. With the additional details, we aim to resolve this matter promptly and effectively.

Thank you for your cooperation and understanding.

Expected vs. Actual Behavior: How can I set the data flow from socket.getInputStream() to sink?
Steps to Reproduce: I modified taint-config.yml
`sources:

  • { kind: call, method: "<java.net.Socket: java.io.InputStream getInputStream()>", index: result}
    sinks:
  • { kind: call, method: "<java.lang.Runtime: java.lang.Process exec(java.lang.String)>", index: 0 }`
    Your Attempts to Resolve the Issue:
    Runtime Environment: java19
    Tai-e Version: 0.2.2

Thanks for providing more detailed info.

Based on your description and examples, it seems that there is a certain distance in the data flow from socket.getInputStream() to the sink.

You have already handled the source and sink (both ends of the dataflow), and next, you should explore how dataflow broke down and MAY need to add some transfers. Please refer to the documentation Taint Analysis for specific details.

After modification, some data streams are generated.

digraph G {
node [];
edge [];
"VarNode{<sun.misc.JarIndex: void read(java.io.InputStream)>/r10}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<java.util.ServiceLoader: int parseLine(java.lang.Class,java.net.URL,java.io.BufferedReader,int,java.util.List)>/$r1}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<sun.misc.MetaIndex: void registerDirectory(java.io.File)>/$r14}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<sun.misc.JarIndex: void read(java.io.InputStream)>/$r4}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<sun.misc.MetaIndex: void registerDirectory(java.io.File)>/$r6}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<org.example.test.TestTaiE: void main(java.lang.String[])>/$r5}" [fillcolor=gold,shape=doubleoctagon,style=filled];
"VarNode{<org.example.test.TestTaiE: void sink(java.lang.String)>/r1}" [fillcolor=deepskyblue,shape=doubleoctagon,style=filled];
"VarNode{<org.example.test.TestTaiE: void main(java.lang.String[])>/$r5}" -> "VarNode{<org.example.test.TestTaiE: void sink(java.lang.String)>/r1}" [color=blue];
}

I'm not sure if this data flow is working properly. Please check it out because it feels strange to me.

I've received your message and fully understand that you are currently facing challenges with the data flow not performing as expected. I'm genuinely eager and committed to assisting you in resolving this issue. I'm here to offer all the support I can to troubleshoot this problem effectively. However, the absence of a replicable example is a significant hurdle. And I can't delve into the context needed for an in-depth troubleshooting process. If I had a concrete example to quickly replicate your scenario, I would spare no effort in debugging and resolving this problem for you. That being said, I'd like to provide some general strategies that could be beneficial: You may want to enable the dump option for pointer analysis. This action will dump the points-to set, allowing you to track the specific taint object you're focusing on. This way, you can investigate which pointers are expectantly or unexpectantly pointing to this taint object. Besides, given that the analysis operates on an intermediate representation, activating the ir-dumper analysis could be advantageous. This will output your program in the .tir format, offering a useful resource for your troubleshooting endeavors. I hope these suggestions are helpful, and I look forward to receiving more detailed information or replicable examples (the example of how to write a reproducible case) from you.

I guess your missing rules may be (The following is not your only answer, but rather depends on what granularity of taint flow you need):

transfers:
  - { method: "<java.io.InputStreamReader: void <init>(java.io.InputStream)>", from: 0, to: base }
  - { method: "<java.io.BufferedReader: void <init>(java.io.Reader)>", from: 0, to: base }
  - { method: "<java.io.BufferedReader: java.lang.String readLine()>", from: base, to: result }

These are the missing (broken) taint flows above I talked about.

Because of the lack of reproducible case, I can only provide rules (based on what I guess) to you, but I cannot verify them for you, you need to verify them yourself.

Continue with any questions you may have.