secure-software-engineering / FlowDroid

FlowDroid Static Data Flow Tracker
GNU Lesser General Public License v2.1
1.02k stars 292 forks source link

No leaks found when using FlowDroid as a library #690

Closed leileidesu closed 5 months ago

leileidesu commented 5 months ago

Hi, I am a beginner to flowdroid and I have a problem now, that is, when I use flowdroid as a library and run soot-infoflow-cmd-2.9.0-jar-with-dependencies.jar, I'll get different results. The library version of flowdroid cannot find leaks in apk. The version I used was 2.10, and the apk I analyzed was very simple, its only purpose being to get the location and write to the file after the program had run. The main code of the apk is as follows:(apk file can be downloaded here

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textViewLocation = findViewById(R.id.textView_location);
        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATION_PERMISSION);
        }
        String filePath = "path/to/your/file.txt";
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            String locationString = "Latitude: " + location.getLatitude() + "\nLongitude: " + location.getLongitude();
            textViewLocation.setText(locationString);
            writer.write(locationString);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

My SourceandSinks.txt is as follows

<android.location.Location: double getLongitude()> -> _SOURCE_
<android.location.Location: double getLatitude()> -> _SOURCE_

<java.io.Writer: void write(java.lang.String)> -> _SINK_

My command line is as follows (it found the leak I was expecting)

java -jar soot-infoflow-cmd-jar-with-dependencies.jar -a ./app-debug.apk -p ./android-21/android.jar -s ./mySourcesAndSinks.txt -o sootOutput.xml -d

My program code is as follows

    public static void main(String[] args) throws XmlPullParserException, IOException {
        InfoflowAndroidConfiguration conf = new InfoflowAndroidConfiguration();
        conf.getAnalysisFileConfig().setAndroidPlatformDir(androidDirPath);
        conf.getAnalysisFileConfig().setTargetAPKFile(apkFilePath);
        conf.getAnalysisFileConfig().setSourceSinkFile(sourceSinkFilePath);
        conf.setLogSourcesAndSinks(true);
        conf.setMergeDexFiles(true);
        SetupApplication setup = new SetupApplication(conf);
        res = setup.runInfoflow();
    }

The cli output log is as follows:

cli_output.txt

The output of the program is as follows:

lib_output.txt

I hope I get the right result when I use flowdroid as a library because it's more convenient and flexible, I wonder what caused the different results, I have checked other issues and can't find out what the problem is, my question may be very stupid, thank you very much for your time!

timll commented 5 months ago

Hi @leileidesu,

your path from source to sink contains a StringBuilder (+ is compiled to a StringBuilder). The Android.jar from Android Studio only contains stubs, i.e. no method body. Obviously, FlowDroid isn't able to deduce a flow without a method body. For the standard library, we use short-cut rules instead, which are provided by a TaintWrapper. The command-line tool enables one by default.

https://github.com/secure-software-engineering/FlowDroid/blob/develop/soot-infoflow-cmd/src/soot/jimple/infoflow/cmd/MainClass.java#L423

leileidesu commented 5 months ago

Thank you very much! By adding setup.setTaintWrapper(new EasyTaintWrapper(taintWrapperFilePath)); I successfully solved my problem, thank you very much! Have a nice day