ImranR98 / Obtainium

Get Android app updates straight from the source.
https://obtainium.imranr.dev
GNU General Public License v3.0
7.56k stars 165 forks source link

feature request: verify signing certificate of apk with sha256 (and ideally other) fingerprints if a fingerprint is provided #255

Closed zombiehoffa closed 6 months ago

zombiehoffa commented 1 year ago

It would be great if we could verify the signing certificate on the apk matches for apps such as signal that provide that ability

https://signal.org/android/apk/

thestinger commented 9 months ago

Of course. The issue is, how to confirm that's actually the developer's key. We don't have key servers, for example, providing those keys. There is no "Web of Trust." etc.

Key servers are a misfeature. It only gives the illusion of providing something useful for retrieving a key. It's unsafe to use keyservers with GPG since it's not protected against attacks from them, and similarly importing keys another way is also quite dangerous. People sign keys all the time without really confirming anything. My legacy GPG key received many signatures and none of them ever really confirmed my identity.

thestinger commented 9 months ago

Yes unfortunately there is no "Web of Trust" equivalent in android ecosystem, however I would argue that App Verifier approach is sufficient in most of the cases and it is much better than nothing. It is done through cross-verification of APK signature fingerprints. The App Verifier database consists of signature fingerprints retrieved from official APK sources. Contributors submit signature fingerprints of apps and the main dev cross-verifies them. In case something happens (e.g. key ration, key compromise, failed verification) a contributor may open an issue and the fingerprints in question will be reviewed.

A well maintained database of pinned public keys is far better than the "web of trust" and this is fortunate, not unfortunate.

life00 commented 9 months ago

A well maintained database of pinned public keys is far better than the "web of trust" and this is fortunate, not unfortunate.

Yeah I heard such criticism but I am not familiar with this topic. Thanks for clarification.

life00 commented 9 months ago

Just checked out AppVerifier, seems to work really well + it automatically verifies installed apps with its built in DB. Instead of trying to duplicate functionality in Obtainium, maybe it would make sense for AppVerifier to provide a method for other apps to use it without user interaction? Obtainium could send the APK (via an intent?) and AppVerifier could return a success/fail result. This would be an optional/recommended feature for users with AppVerifier installed. If it doesn't already provide functionality like this (and they're open to it) I could create an issue.

https://github.com/ImranR98/Obtainium/issues/255#issuecomment-1880097316

@soupslurpr

This sound good!

soupslurpr commented 9 months ago

Just checked out AppVerifier, seems to work really well + it automatically verifies installed apps with its built in DB. Instead of trying to duplicate functionality in Obtainium, maybe it would make sense for AppVerifier to provide a method for other apps to use it without user interaction? Obtainium could send the APK (via an intent?) and AppVerifier could return a success/fail result. This would be an optional/recommended feature for users with AppVerifier installed. If it doesn't already provide functionality like this (and they're open to it) I could create an issue.

AppVerifier doesn't currently have functionality like that. I could try to see if I can add it. The internal database status has 3 states: MATCH, NOMATCH, and NOT_FOUND

soupslurpr commented 9 months ago

@ImranR98 What do you think about AppVerifier accepting an intent that has a uri to an apk file as its EXTRA_STREAM? It opens AppVerifier with the verify app screen for that apk. Pressing back would go back to the app that opened it using the intent (Obtainium).

ImranR98 commented 9 months ago

@soupslurpr yes, that would work.

In the simplest case, Obtainium would open AppVerifier with the intent, then when they return, prompt them to continue or cancel installation based on what they observed on the AppVerifier results screen.

Would it be possible for AppVerifier to also send the verification result back to Obtainium after the user goes back? This would avoid the need for another confirmation box.

soupslurpr commented 9 months ago

I'm not sure how to send the result back to Obtainium in that situation, is that even possible?

ImranR98 commented 9 months ago

@soupslurpr no idea 🫠 It might be, but we can just go with the simpler confirmation box approach.

Also, assuming the URI is somewhere in Obtainium's data directory, do you know if it would need to be moved elsewhere for AppVerifier to access it? Or does Android allow it since it was passed via an intent?

soupslurpr commented 9 months ago

@ImranR98 "The receiving application needs permission to access the data the Uri points to. There are two recommended ways to do this:" https://developer.android.com/training/sharing/send#:~:text=The%20receiving%20application%20needs%20permission%20to%20access%20the%20data%20the%20Uri%20points%20to.%20There%20are%20two%20recommended%20ways%20to%20do%20this%3A

DiagonalArg commented 9 months ago

A well maintained database of pinned public keys is far better than the "web of trust" and this is fortunate, not unfortunate.

I think the question is, how do you create, and then distribute, this DB? The system of individuals submitting via PR and distribution on update of the app is clunky, to say the least.

If the model is like Convergence, then peoples' verifications can be accumulated. If we think there's one person who can go through all of those by hand and do a good job of it, then we'll want that individual to do the pinning. Otherwise, we might want to accumulate community "votes" and share that.

Note, the the point of Convergence was that the internet might be intercepted for one person accessing a website, but not for another. So each person would see a different signing certificate/ key. (That's the NSA's quantum something attack - the name escapes me now.) So if that's your threat model, and in which case the person doing the pinning might be a good target, you actually want to see the results from many Perspectives (which was the prior name of Convergence.)

soupslurpr commented 9 months ago

@ImranR98 AppVerifier 0.6.0 supports the VIEW and SEND intent to open APK files!

ImranR98 commented 9 months ago

Great! Now I just need to figure out how to use ContentProvider to share the APK.

Nemes15 commented 9 months ago

@ImranR98 @thestinger it might be an impossible thing to ask, but isn't there a way for us ungoogled persons to verify the base public hash from the "known pool", verify any signatures to match previously provided APKs and validity dates (not unlike virustotal does for executables) and verify the latest hash (if available from github or source provided) automatically on install through various scrapers? This might be expensive to run for AOSP projects or apps such as AppVerifier (thank you for the update @soupslurpr ) but as a combined FOSS it might be possible with scraping. That way even the most inexperienced new de-googled users (and we want more of those? Don't we?) Will feel safe and secure installing that "dangerous APK" Google always warned them for.

This isnt a zeroday solution but isn't it what all of us want? Have privacy, be mindful yet not paranoid about each install they perform? It does not negate MiTM, but maybe some day. I think most users want as safe and secure ease of use now. Even if it requires sha checks from the same APK hosts. It is, and both, is not, better than nothing at the same time (i remember CCleaner which ran amok too long before discovered, but its something).

soupslurpr commented 8 months ago

@nemes15 you seem to be misunderstanding, AppVerifier verifies the hash of the signing certificate which usually does not change every release for an app. "verify the latest hash (if available from github or source provided) automatically on install through various scrapers" would be security theater. If the app can be changed to a malicious version so can the hash posted on the same source.

AppVerifier has a database of app signing certificate hashes included with it and every entry is manually verified by me by downloading the app from the places it is available from.

ImranR98 commented 6 months ago

AppVerifier has been integrated in the latest release: https://github.com/ImranR98/Obtainium/releases/tag/v1.1.0

It's not perfect since the user needs to manually select AppVerifier from the share sheet, but I wasn't able to figure out a more seamless way at this point.

The user also needs to manually click install/cancel - we can't grab the results from AppVerifier to do so automatically.

soupslurpr commented 6 months ago

Awesome!

DiagonalArg commented 6 months ago

For those who aren't groking what a "share sheet" is, I found it in settings: "Share new Apps with AppVerifier (if available)"

ImranR98 commented 6 months ago

@DiagonalArg the share sheet is what comes up when you're about to install a new app (if you have appverifier installed). The new setting enables this.

soupslurpr commented 6 months ago

AppVerifier has a database of app signing certificate hashes included with it and every entry is manually verified by me by downloading the app from the places it is available from.

Is there a public list where we could see what app hashes are currently included?

@3knight Sure, look at https://github.com/soupslurpr/AppVerifier/blob/master/app/src/main/kotlin/dev/soupslurpr/appverifier/InternalVerificationInfoDatabase.kt

atlantis451 commented 3 weeks ago

Signed Certificate Hash verifier should be done before the app is installed, not after. app sha256 list https://apps.obtainium.imranr.dev/AppVerifier.json verifier It should be done in Obtainium, not through some other.