About reference type casting in taint propagation
Closed this issue · 2 comments
Description
package structure:
pet
├── Main.java
├── Pet.java
├── PetFactory.java
├── SmallPet.java
└── SmallPetFactory.java
public abstract class Pet { }
public abstract class PetFactory {
public abstract Pet createPet();
}
public class SmallPet extends Pet{
public void sink() {
System.out.println("sink of small pet");
}
}
public class SmallPetFactory extends PetFactory{
public Pet createPet() {
return new SmallPet();
}
}
public class Main {
public static void main(String[] args) {
SmallPetFactory spf = new SmallPetFactory();
SmallPet sp = (SmallPet) spf.createPet();
sp.sink();
}
}
I use Tai-e to do the taint analysis with configurations as follows:
sources:
- { kind: call, method: "<pet.SmallPetFactory: pet.Pet createPet()>", index: result }
sinks:
- { method: "<pet.SmallPet: void sink()>", index: base }
The analysis results show that there is no taint flow detected.
Some information provided by tir
and pta-result
:
public static void main(java.lang.String[] r3) {
pet.SmallPetFactory $r0;
pet.Pet $r1;
pet.SmallPet r2;
[0@L5] $r0 = new pet.SmallPetFactory;
[1@L5] invokespecial $r0.<pet.SmallPetFactory: void <init>()>();
[2@L6] $r1 = invokevirtual $r0.<pet.SmallPetFactory: pet.Pet createPet()>();
[3@L6] r2 = (pet.SmallPet) $r1;
[4@L7] invokevirtual r2.<pet.SmallPet: void sink()>();
[5@L8] return;
}
'<pet.Main: void main(java.lang.String[])>':
...
...
- var: "$r1"
pts:
- context: "[]"
objects:
- "[NewObj{<pet.Main: void main(java.lang.String[])>[0@L5] new pet.SmallPetFactory}]:NewObj{<pet.SmallPetFactory: pet.Pet createPet()>[0@L5] new pet.SmallPet}"
- "[]:TaintObj{alloc=<pet.Main: void main(java.lang.String[])>[2@L6] $r1 = invokevirtual $r0.createPet()/result,type=pet.Pet}"
- var: "r2"
pts:
- context: "[]"
objects:
- "[NewObj{<pet.Main: void main(java.lang.String[])>[0@L5] new pet.SmallPetFactory}]:NewObj{<pet.SmallPetFactory: pet.Pet createPet()>[0@L5] new pet.SmallPet}"
...
I think it's reasonable if the taint obj can be propagated to r2
. However, it seems that the reference type casting in [3@L6] r2 = (pet.SmallPet) $r1;
cut off the taint flow so that r2
in main
does not point to the taint obj.
TL;DR :
Just change:
sources:
- - { kind: call, method: "<pet.SmallPetFactory: pet.Pet createPet()>", index: result }
+ - { kind: call, method: "<pet.SmallPetFactory: pet.Pet createPet()>", index: result, type: pet.SmallPet }
Thanks for your detailed info which save repeated communications and your/my time. 👍👍👍
This is a configuration-related issue.
According to https://tai-e.pascal-lab.net/docs/current/reference/en/taint-analysis.html#call-sources,
We use underlining to emphasize the optional nature of type: TYPE in call source configuration. When it is not specified, the taint analysis will utilize the corresponding declared type from the method.
your SOURCE configuration will produce a taint obj of type pet.Pet
, which will fail to cast to SmallPet
in [3@L6] r2 = (pet.SmallPet) $r1
;.
It worked, thanks!