pascal-lab/Tai-e

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!