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

How to resolve taint propagation in type cast #96

Open
Raul1718 opened this issue Apr 2, 2024 · 7 comments
Open

How to resolve taint propagation in type cast #96

Raul1718 opened this issue Apr 2, 2024 · 7 comments

Comments

@Raul1718
Copy link

Raul1718 commented Apr 2, 2024

Description

Hi,

When I was testing the taint analysis plugin, I found an issues in type cast. It seems that current pointer analysis engine could not resolve the assignment relation in type cast now.

I created a test case using the get method of java.util.Map, the signature show below and config into my yaml file.

  - { method: "<java.util.Map: java.lang.Object put(java.lang.Object,java.lang.Object)>", from: 1, to: base }
  - { method: "<java.util.Map: java.lang.Object get(java.lang.Object)>", from: base, to: result }

And The test case code shown below:

import java.util.HashMap;

class ArgToResultMap {
    public static void main(String[] args) {
        String taint = SourceSink.source();
        java.util.Map<String,String> map = new HashMap();
        map.put("test", taint);
        String s2 = map.get("test");
        SourceSink.sink(s2); 
    }
}

The result tir code:

public static void main(java.lang.String[] r4) {
        java.lang.String $r0, %stringconst0, r3;
        java.util.HashMap $r1;
        java.lang.Object $r2;
        [0@L6] $r0 = invokestatic <SourceSink: java.lang.String source()>();
        [1@L7] $r1 = new java.util.HashMap;
        [2@L7] invokespecial $r1.<java.util.HashMap: void <init>()>();
        [3@L8] %stringconst0 = "test";
        [4@L8] invokeinterface $r1.<java.util.Map: java.lang.Object put(java.lang.Object,java.lang.Object)>(%stringconst0, $r0);
        [5@L9] $r2 = invokeinterface $r1.<java.util.Map: java.lang.Object get(java.lang.Object)>(%stringconst0);
        [6@L9] r3 = (java.lang.String) $r2;
        [7@L10] invokestatic <SourceSink: void sink(java.lang.String)>(r3);
        [8@L11] return;
    }

The propagation interrupted in [6@L9] r3 = (java.lang.String) $r2;
In the pta-results.txt, I found r3 was pointed to nothing: []:<ArgToResultMap: void main(java.lang.String[])>/r3 -> []

[]:<ArgToResultMap: void main(java.lang.String[])>/$r0 -> [[]:MergedObj{<Merged java.lang.String>}, []:TaintObj{alloc=<ArgToResultMap: void main(java.lang.String[])>[0@L6] $r0 = invokestatic SourceSink.source()/result,type=java.lang.String}]
[]:<ArgToResultMap: void main(java.lang.String[])>/$r1 -> [[]:NewObj{<ArgToResultMap: void main(java.lang.String[])>[1@L7] new java.util.HashMap}, []:TaintObj{alloc=<ArgToResultMap: void main(java.lang.String[])>[0@L6] $r0 = invokestatic SourceSink.source()/result,type=java.util.Map}]
[]:<ArgToResultMap: void main(java.lang.String[])>/$r2 -> [[]:TaintObj{alloc=<ArgToResultMap: void main(java.lang.String[])>[0@L6] $r0 = invokestatic SourceSink.source()/result,type=java.lang.Object}]
[]:<ArgToResultMap: void main(java.lang.String[])>/%stringconst0 -> [[]:ConstantObj{java.lang.String: "test"}]
[]:<ArgToResultMap: void main(java.lang.String[])>/r3 -> []

There maybe analysis wrong in type cast, or here missing the corresponding pointer propagation.
How could I correct or resolve the type cast transfer.

Thanks!

MacOs
IDEA
Ta-e version:master branch, commit id: 4c6b337c92e9122051c80cd58028f07816ad9e1e(Commits on Dec 29, 2023)

@zhangt2333
Copy link
Member

Thanks for the detailed and helpful issue description.

But I noticed that the steps cannot reproduce the result you give.

Anyway, Maybe the following is what you want?

  - { method: "<java.util.HashMap: java.lang.Object put(java.lang.Object,java.lang.Object)>", from: 1, to: base }
  - { method: "<java.util.HashMap: java.lang.Object get(java.lang.Object)>", from: base, to: result, type: "java.lang.String" }

@Raul1718
Copy link
Author

Raul1718 commented Apr 2, 2024

call-site-mode: true

I also set call-site-mode, so it could config through java.util.Map?

@Raul1718
Copy link
Author

Raul1718 commented Apr 2, 2024

Let me try with the type configuration, thanks
But when I want to analyzer other type (not String) in Map, how to do?

@zhangt2333
Copy link
Member

But when I want to analyzer other type (not String) in Map, how to do?

Currently I do not have a better solution. I think there won't be too many configuration rules based on your actual needs.

@Raul1718
Copy link
Author

Raul1718 commented Apr 2, 2024

Thanks a lot, master!

  • { method: "<java.util.HashMap: java.lang.Object put(java.lang.Object,java.lang.Object)>", from: 1, to: base }
  • { method: "<java.util.HashMap: java.lang.Object get(java.lang.Object)>", from: base, to: result, type: "java.lang.String" }

It worked in the test case shown above.

@Raul1718
Copy link
Author

Raul1718 commented Apr 3, 2024

Like this

for (HandleFunctionInfo functionInfo : params) { 
...
}
[8@L82] $r4 = invokeinterface params.<java.util.List: java.util.Iterator iterator()>();
[9@L82] $z0 = invokeinterface $r4.<java.util.Iterator: boolean hasNext()>();
[10@L82] %intconst1 = 0;
[11@L82] if ($z0 == %intconst1) goto 35;
[12@L82] $r5 = invokeinterface $r4.<java.util.Iterator: java.lang.Object next()>();
[13@L82] r6 = (com.xxx.xxx.xxx.xxxx.HandleFunctionInfo) $r5;

I also need to config the type com.xxx.xxx.xxx.xxxx.HandleFunctionInfo into the rule?
But actually, we usually could not know the type for target project code.

<java.util.Iterator: java.lang.Object next()>", from: base, to: result, type: "com.xxx.xxx.xxx.xxxx.HandleFunctionInfo" }

@zhangt2333
Copy link
Member

zhangt2333 commented Apr 9, 2024

I've been thinking about this for a while and realized I've fallen into a trap (Besides, you never posted the run arguments in your description😵‍💫).

Let me re-answer the whole issue.


The code snippet

import java.util.HashMap;
class ArgToResultMap {
    public static void main(String[] args) {
        String taint = SourceSink.source();
        java.util.Map<String,String> map = new HashMap();
        map.put("test", taint);
        String s2 = map.get("test");
        SourceSink.sink(s2); 
    }
}

can be analyzed directly to detect the taint flow TaintFlow{<ArgToResultMap: void main(java.lang.String[])>[0@L3] temp$0 = invokestatic SourceSink.source()/result -> <ArgToResultMap: void main(java.lang.String[])>[11@L7] invokestatic SourceSink.sink(s2)/0}.

This was originally the POWER of P/Taint Analysis (taint analysis based on pointer analysis).

And you need to set the pointer analysis option only-app to false.

Here are my runtime arguments:

public class MyMain {
    public static void main(String[] args) {
        pascal.taie.Main.main(
                "-pp",
                "-cp", "src/test/resources/pta/taint",
                "-m", "ArgToResultMap", // src/test/resources/pta/tain/ArgToResultMap.java contains the above code snippet
                "-a", """
                        pta=
                        implicit-entries:false;
                        only-app:false;
                        distinguish-string-constants:all;
                        taint-config:src/test/resources/pta/taint/taint-config.yml;
                        """
        );
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants