MM2-0 / Kvaesitso

A search-focused Android launcher
https://kvaesitso.mm20.de/
GNU General Public License v3.0
2.4k stars 74 forks source link

question on permissions #704

Closed IzzySoft closed 6 months ago

IzzySoft commented 7 months ago

My scanner got some new checks in January, and on today's update had a lot to report:

! repo/de.mm20.launcher2.release_2024022100.apk declares flag(s): usesCleartextTraffic
! repo/de.mm20.launcher2.release_2024022100.apk declares intent-filter(s):
  android.accessibilityservice.AccessibilityService
! repo/de.mm20.launcher2.release_2024022100.apk declares sensitive permission(s):
  android.permission.ACCESS_COARSE_LOCATION android.permission.ACCESS_FINE_LOCATION
  android.permission.READ_CONTACTS android.permission.WRITE_CONTACTS
  android.permission.READ_EXTERNAL_STORAGE android.permission.MANAGE_EXTERNAL_STORAGE
  android.permission.REQUEST_INSTALL_PACKAGES android.permission.QUERY_ALL_PACKAGES
  android.permission.REQUEST_DELETE_PACKAGES
! repo/de.mm20.launcher2.release_2024022100.apk contains signature block blobs: 0x504b4453 (DEPENDENCY_INFO_BLOCK; GOOGLE)

I was able to clarify READ_CONTACTS as being used for the search functionality, and of course QUERY_ALL_PACKAGES for the app drawer. But what are the other permissions needed for? And why is AccessibilityService needed? What cleartext (http without encryption) connections are being used?

As for DEPENDENCY_INFO_BLOCK, this is easy to get cleared:

android {
    dependenciesInfo {
        // Disables dependency metadata when building APKs.
        includeInApk = false
        // Disables dependency metadata when building Android App Bundles.
        includeInBundle = false
    }
}

For some background: that BLOB is supposed to be just a binary representation of your app's dependency tree. But as it's encrypted with a public key belonging to Google, only Google can read it – and nobody else can even verify what it really contains.

IzzySoft commented 7 months ago

PS: Yes, I've searched the documentation, code and issues, but couldn't find an answer…

MM2-0 commented 7 months ago
IzzySoft commented 7 months ago

Thanks! So here we go so far:

image

Be welcome to fill in the other gaps if you wish, I'll gladly add that then. May help keeping future questions away (I guess that e.g. ACCESS_MEDIA_LOCATION will be added to "sensitive permissions" as well).

write contacts: unused, didn't know that was there lol

So will you remove it with the next release? Still missing: REQUEST_DELETE_PACKAGES. And still there and were better missing: DEPENDENCY_INFO_BLOCK (will you try keeping it out with the gradle snippet provided?)…

MM2-0 commented 7 months ago

So will you remove it with the next release

I will make sure again whether it is used anywhere but if not I'll remove it

And still there and were better missing: DEPENDENCY_INFO_BLOCK (will you try keeping it out with the gradle snippet provided?)…

I can try, but what is its purpose?

IzzySoft commented 7 months ago

Thanks! Added the other two – and look forward to see the third one gone. Should you be unable to locate the culprit, you can try this: Removing Unwanted Manifest Permissions With tools:node

I can try, but what is its purpose?

Security and transparency. As outlined above, nobody except Google can read what's inside. And those blobs can be a security risk. We've just ran a POC, I can take the APK you've signed and put anything inside such a signing block blob. Verification would not show my changes, malware scanner would not yell (only 2 out of VT's 64 engines detected an EICAR sample placed inside – and literally NOT A SINGLE ONE detected an ELF binary paced inside. Done right, neither Androguard nor ApkSigner would even see that blob (my scanner would).

So TL;DR: like with other blobs, with FOSS it's better they are not present. What isn't there cannot pose a risk.

MM2-0 commented 6 months ago

Closed in 5a7f7ef and 38ec6a1

MM2-0 commented 4 months ago

@IzzySoft I had to revert the DEPENDENCY_INFO_BLOCK thing, because apparently without it, Google Play Protect flags my app as malware, and my users can't install it anymore.

IzzySoft commented 4 months ago

That's very unfortunate. This blob will soon become an anti-feature, as it's a proprietary blob. The malware here is obviously PlayProtect, trying to force people into their eco-system. You're sure this is the trigger and nothing else? And folks cannot install it nevertheless (by ignoring the inappropriate and misleading message PlayProtect shows)? First time I hear this, and there are plenty of apps without that blob in the repo here.

MM2-0 commented 4 months ago

The malware here is obviously PlayProtect, trying to force people into their eco-system.

True, but I don't think it's responsible to advise my users to disable Play Protect altogether

You're sure this is the trigger and nothing else?

I had reports from ~5 different people that they couldn't install versions 1.30.0-1.30.2 because of Play Protect and at least 3 people reporting that they could install 1.30.3. The only change in that version was, that I reenabled the dependency info block. It's not a huge sample size so there could be something else at play, but I know for certain that it affects it in some way.

And folks cannot install it nevertheless (by ignoring the inappropriate and misleading message PlayProtect shows)

I don't know, I didn't face the issue myself, but at least it doesn't seem to be trivial (otherwise people wouldn't have asked for assistance) and the only proposed solution by other users was to disable Play Protect altogether.

First time I hear this, and there are plenty of apps without that blob in the repo here.

My guess is that Play Protect becomes suspicious by the amount of sensitive permissions the launcher requests (especially the accessibility service). And the missing dependency info block is just the final nail in the coffin.

That's very unfortunate. This blob will soon become an anti-feature, as it's a proprietary blob.

I wonder if it only affects users who are trying to sideload the APK. Maybe, if it doesn't affect app stores (like F-Droid), I could disable it in the F-Droid build flavor but keep it enabled for the Github version.

IzzySoft commented 4 months ago

My guess is that Play Protect becomes suspicious by the amount of sensitive permissions the launcher requests (especially the accessibility service). And the missing dependency info block is just the final nail in the coffin.

I've just asked in my team, and that was the same conclusion I got as response. In that case it would even make sense, to a degree – if they made that clear ("blabla risk because of blabla permission whatever, are you sure you want to proceed?"). But them making it all a blackbox, together with their history, is not especially establishing any trust. If you look at results at VirusTotal, a scanner named "Google" is the only one never giving a reason, just saying "found". Same thing.

Maybe, if it doesn't affect app stores (like F-Droid)

Where did those reporters install from, or by what means? Did they use an F-Droid client and the IzzyOnDroid repo, or "sideload" it otherwise? In the latter case, you could consider offering an APK with that blob here in addition to the one pulled by IzzyOnDroid (we could establish means to not get the two messed up).

MM2-0 commented 4 months ago

Where did those reporters install from, or by what means? Did they use an F-Droid client and the IzzyOnDroid repo, or "sideload" it otherwise?

At least some of them sideloaded the APK from Github. I haven't heard of anyone yet having issues when they tried to install the update from an F-Droid client.

IzzySoft commented 4 months ago

OK, worth a try then maybe. Could you add the non-blobbed APK as well (e.g. starting with the next release, and maybe include a -noblob or so in the file name)? Let me know then so I can prepare my updater to focus on that.

This way those affected could easily switch, provided both apps have the same PackageName and Signing key.

IzzySoft commented 4 months ago

And PS, maybe worth a try: https://support.google.com/googleplay/android-developer/contact/protectappeals