The CLI output detected the taint flow, but no flow in the dot file.
Closed this issue · 3 comments
source code
public class Main {
public static void main(String[] args) {
test1();
}
public static void test1(){
String a = getSourceString();
String [] b;
b = a.split(":");
TestSink.testStringSink(b[0]);
}
public static String getSourceString(){
return "test1:test2";
}
}
IR
public static void test1() {
java.lang.String $r0, %stringconst0, $r2;
java.lang.String[] $r1;
int %intconst1;
[0@L12] $r0 = invokestatic <org.example.Main: java.lang.String getSourceString()>();
[1@L15] %stringconst0 = ":";
[2@L15] $r1 = invokevirtual $r0.<java.lang.String: java.lang.String[] split(java.lang.String)>(%stringconst0);
[3@L17] %intconst1 = 0;
[4@L17] $r2 = $r1[%intconst1];
[5@L17] invokestatic <org.example.TestSink: void testStringSink(java.lang.String)>($r2);
[6@L18] return;
}
tai-e options
- options
analyses:
pta: cs:ci;implicit-entries:true;distinguish-string-constants:null;reflection-inference:solar;taint-config:java-benchmarks/common-text/taint-config.yml;
- taint-config
sources:
- { kind: call, method: "<org.example.Main: java.lang.String getSourceString()>", index: result }
sinks:
- { method: "<org.example.TestSink: void testStringSink(java.lang.String)>", index: 0 }
transfers:
- { method: "<java.lang.String: java.lang.String[] split(java.lang.String)>", from: base, to: "result[*]" }
output
- cli
TaintConfig:
sources:
CallSource{<org.example.Main: java.lang.String getSourceString()>/result(java.lang.String)}
CallSource{<org.example.Main: java.lang.String[] getSourceStringArray()>/result(java.lang.String[])}
sinks:
<org.example.TestSink: void testStringSink(java.lang.String)>/0
[Pointer analysis] elapsed time: 5.47s
Detected 1 taint flow(s):
TaintFlow{<org.example.Main: void test1()>[0@L11] $r0 = invokestatic org.example.Main.getSourceString()/result -> <org.example.Main: void test1()>[5@L16] invokestatic org.example.TestSink.testStringSink($r2)/0}
TFGDumper starts ...
Source nodes:
VarNode{<org.example.Main: void test1()>/$r0}
Sink nodes:
VarNode{<org.example.Main: void test1()>/$r2}
question
- Is the output without edge in dot file as expected?
I think expected result should have at least 2 point flow edge:$r0 -> $r1
and$r1 -> $r2
There is essentially no $r0
to $r1
edge in OFG ($r1
is an array); that's why it's not showing up.
One actual propagation chain in TFG is:
VarNode{<org.example.Main: void test1()>/$r0}
ArrayIndexNode{NewObj{<java.util.regex.Pattern: java.lang.String[] split(java.lang.CharSequence,int)>[33@L1015] newarray java.lang.String[%intconst1]}}
VarNode{<org.example.Main: void test1()>/$r2}
You could try reversing the switch
which is used to filter the edge from app to non-app when traveling the OFG
Tai-e/src/main/java/pascal/taie/analysis/pta/plugin/taint/TFGBuilder.java
Lines 133 to 135 in 8e5db8b
to get the complete graph.
One actual propagation chain is:
VarNode{<org.example.Main: void test1()>/$r0} ArrayIndexNode{NewObj{<java.util.regex.Pattern: java.lang.String[] split(java.lang.CharSequence,int)>[33@L1015] newarray java.lang.String[%intconst1]}} VarNode{<org.example.Main: void test1()>/$r2}
Is there a taint-config rule that can get this "actual propagation chain"?
The above actual propagation chain I mentioned, one of shortest paths from $r0
to $r2
, is reflected in the complete TFG. You can modify the source code to reversing the switch) to produce it.
Besides, if you think the obtained TFG too large for checking conveniently (that's why we haven't made the switch a configurable option for the time being), you can modify the buildComplete
method to search (BFS/Shortest-path/...) the paths you want.