Relax in-app updater policy for RB apps
So now that #3110 (closed) is closed and handled, there's no more immediate stress about bending policy or policy changes, so I'd like to now propose something constructive.
Consider that I'm a malicious fake open source developer with an app in F-Droid and I'd like to ship some closed source user tracking blob that does all sorts of nasty. What is the best way for me to go about it?
- Make sure
AutoUpdateMode/UpdateCheckModeworks reliably. - Bury it in my code repo -- perhaps with some maze of gradle code to fetch it, or maybe I encode it in the whitespace of source files, or something trixy like that -- and then wait for an update to ship on F-Droid.
- Profit?
It would be months, if ever, until F-Droid catches on. And if I structured this in a "plausibly deniable" way, I could just say oopsie, remove it, and then try again a few months later. Actually, I'm pretty sure this exact process happens frequently, but unintentionally, by app developers who accidentally get some dep that doesn't have source. Probably many cases are never noticed. The ones that are are rectified and might break later.
In other words, it's an imperfect process. But that's fine and just part of F-Droid. Over time more things will be automated maybe. But that, anyhow, is the way to ship nasty code, intentional or not, in F-Droid apps.
Meanwhile, the in-app updater policy is designed around the threat of app developers shipping updates that F-Droid can't tend to. The in-app updater, itself, is one of these pieces of code that F-Droid has to police like it does binary blobs; if it doesn't meet the specs, it can't be in F-Droid. If the updater is going to ship an app that won't be in F-Droid, then it has to make that realllly clear to users. It's not supposed to be an escape hatch from the protections that F-Droid has through its attention to apps in its repository.
This all makes sense to me and I don't object to it. You don't want a user to get an app from F-Droid and then for it to update to some proprietary junk, at least without having very clear an explicit user consent, informing them that the update will bring them out of F-Droid and expose them (potentially) to proprietary junk.
Here's where my proposal comes into play: what if you could assure that the in-app updater is going to ship the same code -- byte-for-byte -- that F-Droid will ship? In that case, I don't think there'd be much of an objection. It turns out that this kind of guarantee is possible via a combination of reproducible builds and my favorite F-Droid hobby horse, AllowedAPKSigningKeys. It can even be verified in an automated manner!
So my proposal is to relax the in-app updater policy if:
- The in-app updates match what F-Droid ships or will ship within one build cycle, which can be automated.
- If the in-app updater ever ships something different, then versions with that in-app updater are disabled.
You might object - but hey, that means until the next cycle, bad things might happen. But keep in mind that developers can already introduce bad code into their repo for at least one cycle and it'll get built automatically anyway, and is usually only ever manually discoverable. With what I'm proposing, the breach would be automatically discoverable.
And, most appealingly for me, this policy nuance would allow WireGuard -- no doubt an app committed to the free software ethos -- to go back into F-Droid.
Thoughts?