pascal-lab / Tai-e

An easy-to-learn/use static analysis framework for Java
https://tai-e.pascal-lab.net/docs/index.html
GNU Lesser General Public License v3.0
1.34k stars 171 forks source link

How to configure Taint Transfer for such case? #72

Closed 75ACOL closed 8 months ago

75ACOL commented 9 months ago

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);
    }
}
75ACOL commented 9 months ago
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 }
zhangt2333 commented 9 months ago

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:

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.

75ACOL commented 9 months ago

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:

zhangt2333 commented 9 months ago

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.

75ACOL commented 9 months ago

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.

zhangt2333 commented 9 months ago

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.

zhangt2333 commented 8 months ago

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.