-
Notifications
You must be signed in to change notification settings - Fork 300
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
FlowDroid fails to track complete taint flow through Cursor and List operations #774
Comments
Can you please provide your precise source/sink definitions? How did you specify your sources and sinks? Did you create your own Which Taint Wrapper did you specify? Do you run FlowDroid using the API or using the command-line tool? If you use the API, please provide your code. If you used the command-line application, please provide the parameters. If FlowDroid is able to find the individual paths, it should also find the combined path. I suspect that something is wrong with your taint wapper configuration and hence, |
**Thank you, I am new to Flowdroid so I have been encountering some issues. I am using the old plaintext definition and this is my sources and sinks file content** <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <android.database.Cursor: java.lang.String getString(int)> -> SOURCE <com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)> -> SINK **This is currently my source and sink file, please note my actual sink is the zn.NC(oEVar); last line of the app code I provided previously. However, Flowdroid could not identify that as a sink and I have tracked this manually and dynamically using Frida there is a leak as contact data was sent over the network. So, I am trying to track where the taint actually gets lost, and I found out that from the source I can't even track the taint directly for query method to the list. I use this command line parameters** java -Xmx16384m -jar "C:\Users\walea\Desktop\FlowDroid-develop\soot-infoflow-cmd\target\soot-infoflow-cmd-jar-with-dependencies.jar" -a "C:\Apktool\apk_files\easycash.apk" -p "C:\Users\walea\AppData\Local\Android\Sdk\platforms" -s "C:\Users\walea\Desktop\FlowDroid-develop\soot-infoflow-android\ctest.txt" -t "C:\Users\walea\Desktop\FlowDroid-develop\soot-infoflow\ccw.txt" -tw EASY --cgalgo SPARK -o easycash.xml -pr fast -ls -aliasflowins I am also using the plaintext format for my taint wrapper (ccw.txt) content below as I could not find a sample of format <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE This is the result I get [main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink specialinvoke $r9.<com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)>($r7, $r6) in method <ji: java.util.List sd(android.content.Context)> was called with values from the following sources: [main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink specialinvoke $r9.<com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)>($r7, $r6) in method <ji: java.util.List sd(android.content.Context)> was called with values from the following sources: Now I figured when I exclude <android.database.Cursor: java.lang.String getString(int)> -> SOURCE from the sources and sinks file and use my taintwrapper (ccw.txt) flowdroid identifies a leak where the source is from the <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)>($r3, $r4, null, null, null) in method <ji: java.util.List sd(android.content.Context)> method [main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink specialinvoke $r9.<com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)>($r7, $r6) in method <ji: java.util.List sd(android.content.Context)> was called with values from the following sources: Another observation is that when I use the content below in my taintwrapper file no class get loaded. So I am not sure if the first taintwrapper is the correct format because it actually does not specify any taint propagation rule for me to assume flowdroid uses that to understand the flow. However, the results I get say otherwise. Taint Wrapper for EasyTaintWrapper Sources Cursor.getString(int): Propagate taint from 'this' to return value String.trim(): Propagate taint from 'this' to return value LianXiRenClass.getName() and getMobile(): Propagate taint from 'this' to return value List methods: Propagate taint through lists Map methods: Propagate taint through maps JSONObject methods: Propagate taint through JSON objects Base64Utils.encode(byte[]): Propagate taint from parameter to return value oo.sd(byte[], byte[]): Propagate taint from parameters to return value StringBuilder methods: Propagate taint through string building OkGo methods: Propagate taint into the network call Sinks QUESTIONS: The result I am expecting from flowdroid is the flow from the source <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE to the sink <com.lzy.okgo.request.base.BodyRequest: void execute(com.lzy.okgo.callback.Callback)> -> SINK however i am getting no leaks, which prompted me to believe flowdroid lot the taint and tracking was never done till the sink i specified.
|
So basically while trying to observe where taint is lost, these are the pair of sources and sinks I use in to track if taint flows from the source to the methods that handles the taint from the first sink. Note: I am using the taintwrapper, i only change the sink for each run <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <android.database.Cursor: java.lang.String getString(int)> -> SINK the following result was gotten The sink $r7 = interfaceinvoke $r5.<android.database.Cursor: java.lang.String getString(int)>(0) in method <ji: java.util.List sd(android.content.Context)> was called with values from the following sources: <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)> -> SINK the result gotten was [main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink specialinvoke $r9.<com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)>($r7, $r6) in method <ji: java.util.List sd(android.content.Context)> was called with values from the following sources: Sources<android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <java.util.List: boolean add(java.lang.Object)> -> SINK At this point I was not getting any leak related to the ji path So Flowdroid could not track if the list is tainted. However when I use <com.glx.fenmiframe.get_phonebook.LianXiRenClass: java.lang.String getMobile()> -> SOURCE which is after the taint was added to the list as source and this as sink Sinks<org.json.JSONObject: org.json.JSONObject put(java.lang.String,java.lang.Object)> -> SINK Flowdroid could detect leak. So it seems flowdroid lost the taint when <java.util.List: boolean add(java.lang.Object)> was invoked as this is the point where it could no longer detect leak. |
The purpose of the taint wrapper is to provide an abstraction over API methods. You don't need to put any methods from your target app into the definition file. Aside from that, the In the default configuration, the What is your command line? |
I built a small test application with the same |
Thank you for your help so far, I uploaded the app to a drive https://drive.google.com/drive/folders/1Ye6LhU9WFrTgO3XVsCj3TiQi91R2G8Ii?usp=sharing The app retrieves contact data, sms and images hence the need to track this data from source to when they are sent over the network. The classes of interest where this data retrievals happen is the defpackage,ji defpackage.ki and defpackage.mi, at the later end of each class the code structure is similar and the 3 classes all make a call to the zn.NC class for network connection using okGO post method. |
**I ended up specifying taint wrapper because the default configuration where I just specified only the source and sink of interest detects 0 leak and i am sure there is a leak. ** So I have ran flowdroid with these commands
This is the content of my ctest.txt (source and sink file) <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <com.lzy.okgo.OkGo: com.lzy.okgo.request.PostRequest post(java.lang.String)> -> SINK I have tried all default configuration flowdroid still detects 0 leak. By manual observation of the app this <com.lzy.okgo.OkGo: com.lzy.okgo.request.PostRequest post(java.lang.String)> -> SINK should be the source and sink for the contact data that was retrieved. Hence, I expected flowdroid to detect this leak. |
The APK seems to contain malwaree. Google Drive gives me "Only the owner is allowed to download infected files.". Maybe you can upload an encrypted ZIP file and put the password here. |
HI @StevenArzt Just a quick question, hope you now have access to the app? Thank you |
Hi @StevenArzt would like to ask if there is any update from your end as regards the discussed problem with flowdroid detecting leak in the app from where the contact data was tainted till when a post request was made. Thank you. |
Hi @StevenArzt just want to ask if there is any update. Thank you. |
Hi @StevenArzt I have uploaded an encrypted zip file as you requested https://drive.google.com/file/d/1cmKXOWhYkklh1IRy_UVMchdLCCmerP5b/view?usp=sharing pwd: testapp I just want to ask if there is any update. Thank you. |
I have the APK now, thank you. I am quite busy at the moment with reviewing papers for ISSTA, so it might take a bit before I can look into the issue. |
Hi Steven, While you are still busy with the ISSTA paper review, I simplified the problem to the least possible example With the code below: ` private void retrieveAndSendContacts() {
` Using this command line argument: java -Xmx16384m -jar "C:\Users\walea\Desktop\FlowDroid-develop\soot-infoflow-cmd\target\soot-infoflow-cmd-jar-with-dependencies.jar" -a "C:\Apktool\apk_files\testapp\basicapp.apk" -p "C:\Users\walea\AppData\Local\Android\Sdk\platforms" -s "C:\Users\walea\Desktop\FlowDroid-develop\soot-infoflow-android\testapp.txt" -o basicapp.xml -pr fast -ls -d --aliasflowins Flowdroid detects 1 leak from query() to network sink. However, for this second code ` private void retrieveAndSendContacts() {
Source and sink file used for both _ <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)> -> SOURCE <java.net.HttpURLConnection: java.io.OutputStream getOutputStream()> -> SINK |
Hi, @t1mlange @StevenArzt
FlowDroid is not tracking the complete taint flow from ContentResolver.query() through Cursor.getString() and List operations to LianXiRenClass methods. While it can track individual segments of this flow, it fails to connect them into a single end-to-end taint propagation.
These are the step i took
Set up FlowDroid with the following source and sink:
Source: <android.content.ContentResolver: android.database.Cursor query(android.net.Uri,java.lang.String[],java.lang.String,java.lang.String[],java.lang.String)>
Sink: <com.glx.fenmiframe.get_phonebook.LianXiRenClass: void (java.lang.String,java.lang.String)>
This is the code structure:
_package defpackage;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import com.glx.fenmiframe.get_phonebook.LianXiRenClass;
import com.google.android.gms.common.util.Base64Utils;
import com.google.firebase.crashlytics.internal.persistence.CrashlyticsReportPersistence;
import defpackage.zn;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/* compiled from: UpLoadPhoneBookManager.java /
/ renamed from: ji reason: default package /
/ loaded from: classes.dex */
public class ji {
public static final String[] K4 = {"display_name", "data1", "photo_id", "contact_id"};
public static ji oE;
public ScheduledFuture<?> NC;
public String zO;
public final ScheduledExecutorService sd = Executors.newScheduledThreadPool(2);
public List h7 = new ArrayList();
}_
Observed Behavior
Expected Behavior
FlowDroid should track the complete taint flow from ContentResolver.query() through Cursor.getString() and List operations to LianXiRenClass methods.
Is this a known limitation of FlowDroid? If so, are there any workarounds ?
The text was updated successfully, but these errors were encountered: