1
0
mirror of https://github.com/PrivSec-dev/privsec.dev synced 2024-12-22 12:51:34 -05:00

F-Droid Security Issues: Add Snikket case and clarify cert pinning

Signed-off-by: friendly-rabbit-35 <169707731+friendly-rabbit-35@users.noreply.github.com>
This commit is contained in:
friendly-rabbit-35 2024-11-02 09:05:21 -07:00 committed by GitHub
parent fb3513b41b
commit 94a4a13b87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -49,7 +49,19 @@ If you understood correctly the information above, Google can't do this for apps
Huawei AppGallery seems to have a [similar approach](https://developer.huawei.com/consumer/en/doc/distribution/app/20210812) to Google, where submitted apps could be developer-signed, but newer apps will be resigned by Huawei.
## 2. Slow and irregular updates
## 2. F-Droid's ridiculous inclusion policy and its consequences
F-Droid, to carry out its "[passion for Free and Open Source Software](https://f-droid.org/en/about/) (FOSS) on the Android platform", requires that developers adhere to a strict [inclusion policy](https://f-droid.org/en/docs/Inclusion_Policy/) for their app(s) to be hosted on the main repository. Principally, according to this policy, F-Droid requires the source code of an app to exclude any proprietary library or ad service. This stringent mandate has proven to be harmful to developers and even end users.
As a result of F-Droid's inclusion policy, usually, some developers will have to maintain a slightly different version of their codebase for their app to comply with F-Droids requirements. For developers, this means not only spending more time and energy, but also, in some cases, working with libraries and components that may be outdated. Sometimes, the restrictions imposed by F-Droid's inclusion policy have a knock-on effect on end users as well, as demonstrated in the following case with Snikket.
In late 2022, the Snikket project issued a [blog post](https://snikket.org/blog/fdroid-security-warning/) that addressed the users of their app who downloaded it from F-Droid. It sought to allay any panic from users if they receive a warning from F-Droid "telling them that the app [Snikket] has a vulnerability and that they 'recommend uninstalling immediately'". In a [later blog post](https://snikket.org/blog/fdroid-security-update/), Snikket clarified that this warning from F-Droid "wasnt entirely accurate, as the problem wasnt with the Snikket app itself but specifically *F-Droids own build of the app* that was using *an outdated version of the WebRTC library*" (emphasis added).
Indeed, as the first blog post by the Snikket project details, the WebRTC component of Snikket's F-Droid version pulled third-party binaries from Google's Maven repository (which stopped releasing new builds in January 2020), presumably to adhere to the parts of the inclusion policy that forbid the use of "Non-Free" dependencies and build tools. Note that the developer-signed versions of Snikket published on the Play Store were not affected by this issue, for they were built with a modern WebRTC version. Furthermore, the subsequent blog post by Snikket reveals how the older third-party version of WebRTC used for their F-Droid app actually hindered the addition of new improvements to the app from upstream.
Overall, this case study highlights how F-Droid's inclusion policy ultimately harms end users by forcing app developers to adopt potentially decrepit development tools and build processes in service of its regnant FOSS ideology.
## 3. Slow and irregular updates
Since you're adding one more party to the mix, that party is now responsible for delivering proper builds of the app: it's a common thing among traditional Linux distributions and their packaging system. They have to catch up with *upstream* on a regular basis, but very few do it well (Arch Linux comes to my mind). Others, like Debian, prefer making extensive *downstream* changes and delivering security fixes for a subset of vulnerabilities assigned to a CVE (yeah, it's as bad as it sounds, but that's another topic).
Not only does F-Droid require specific changes for the app to comply with its inclusion policy, which often leads to more maintenance work, it also has a rather strange way of triggering new builds. Part of its build process seems to be [automated](https://f-droid.org/en/docs/FAQ_-_App_Developers/), which is the least you could expect. Now here's the thing: app signing keys are on an **air-gapped server** (meaning it's disconnected from any network, at least that's what they claim: see [their recommendations](https://f-droid.org/docs/Building_a_Signing_Server/) for reference), which forces an irregular update cycle where a human has to manually trigger the signing process. It is far from an ideal situation, and you may argue it's the least to be expected since by entrusting all the signing keys to one party, you could also introduce a single point of failure. Should their system be compromised (whether from the inside or the outside), this could lead to serious security issues affecting plenty of users.
@ -58,7 +70,7 @@ Not only does F-Droid require specific changes for the app to comply with its in
Considering all this, and the fact that their build process is often broken using outdated tools, you have to expect **far slower updates** compared to a traditional distribution system. Slow updates mean that you will be exposed to security vulnerabilities more often than you should've been. It would be unwise to have a full browser updated through the F-Droid official repository, for instance. F-Droid third-party repositories somewhat mitigate the issue of slow updates since they can be managed directly by the developer. It isn't ideal either as you will see below.
## 3. Low target API level (SDK) for client & apps
## 4. Low target API level (SDK) for client & apps
SDK stands for *Software Development Kit* and is the collection of software to build apps for a given platform. On Android, a higher SDK level means you'll be able to make use of modern API levels of which each iteration brings **security and privacy improvements**. For instance, API level 31 makes use of all these improvements on Android 12.
As you may already know, Android has a strong sandboxing model where each application is sandboxed. You could say that an app compiled with the highest API level benefits from all the latest improvements brought to the app sandbox; as opposed to outdated apps compiled with older API levels, which have a **weaker sandbox**.
@ -95,7 +107,7 @@ At the time of writing:
*Overall statistics do not reflect real-world usage of a given app (people using old devices are not necessarily using your app). If anything, it should be viewed as an underestimation.*
## 4. General lack of good practices
## 5. General lack of good practices
The F-Droid client allows multiple repositories to coexist within the same app. Many of the issues highlighted above were focused on the main official repository which most of the F-Droid users will use anyway. However, having **other repositories in a single app also violates the security model of Android** which was not designed for this at all. The OS expects you to trust **an app repository as a single source** of apps, yet F-Droid isn't that by design as it mixes several repositories in one single app. This is important because the OS management APIs and features (such as [UserManager](https://developer.android.com/reference/android/os/UserManager) which can be used to prevent a user from installing third-party apps) are not meant for this and see F-Droid as a single source, so you're trusting the app client to not mess up far more than you should, especially when the **privileged extension** comes into the picture.
There is indeed a serious security issue with the OS first-party source feature being misused, as the privileged extension makes use of the `INSTALL_PACKAGES` [API](https://developer.android.com/reference/android/Manifest.permission#INSTALL_PACKAGES) in an insecure manner (i.e. not implementing it with the appropriate security checks). The privileged extension accepts any request from F-Droid, which again suffers from various bugs and security issues and allows user-defined repositories by design. A lot can go wrong, and bypassing security checks for powerful APIs should definitely not be taken lightly.
@ -106,7 +118,9 @@ As a matter of fact, the [new unattended update API](https://developer.android.c
Their client also lacks **TLS certificate pinning**, unlike Play Store which improves security for all connections to Google (they generally use a limited set of root CAs including [their own](https://pki.goog/)). Certificate pinning is a way for apps to increase the security of their connection to services [by providing a set of public key hashes](https://developer.android.com/training/articles/security-config#CertificatePinning) of known-good certificates for these services instead of trusting pre-installed CAs. This can avoid some cases where an interception (*man-in-the-middle* attack) could be possible and lead to various security issues considering you're trusting the app to deliver you other apps.
It is an important security feature that is also straightforward to implement using the [declarative network security configuration](https://developer.android.com/training/articles/security-config) available since Android 7.0 (API level 24). See how GrapheneOS pins both root and CA certificates in their [app repository client](https://github.com/GrapheneOS/Apps):
F-Droid's official client also lacks **TLS certificate pinning**. Certificate pinning is a way for apps to increase the security of their connection to services [by providing a set of public key hashes](https://developer.android.com/training/articles/security-config#CertificatePinning) of known-good certificates for these services instead of trusting pre-installed CAs. This can avoid some cases where an interception (*man-in-the-middle* attack) could be possible and lead to various security issues, considering you're trusting an app to deliver you other apps.
Certificate pinning is an important security feature that is also straightforward to implement using the [declarative network security configuration](https://developer.android.com/training/articles/security-config) available since Android 7.0 (API level 24). The [GrapheneOS App Store](https://github.com/GrapheneOS/AppStore) uses this feature; see how GrapheneOS pins both root and CA certificates in their app repository client:
```xml
<!-- res/xml/network_security_config.xml -->
@ -129,18 +143,20 @@ It is an important security feature that is also straightforward to implement us
</network-security-config>
```
The Play Store does not use certificate pinning exactly, but achieves a similar level of security for all connections to Google by using a limited set of root CAs, including [their own](https://pki.goog/)). This practice, alongside the Play Store's use of [package signing](https://source.android.com/docs/security/features/apksigning) and [properly signed metadata](https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html), guarantees that the apps you download from the Play Store are genuine and delivered securely. F-Droid does **not** provide the same guarantee.
To be fair, they've thought several times about adding certificate pinning to their client [at least for the default repositories](https://gitlab.com/fdroid/fdroidclient/-/issues/105). [Relics of preliminary work](https://gitlab.com/fdroid/fdroidclient/-/blob/1.14-alpha4/app/src/main/java/org/fdroid/fdroid/FDroidCertPins.java) can even be found in their current codebase, but it's unfortunate that they haven't been able to find [any working implementation](https://github.com/f-droid/fdroidclient/commit/7f78b46664981b9b73cadbfdda6391f6fe939c77) so far. Given the overly complex nature of F-Droid, that's largely understandable.
F-Droid also has a problem regarding the adoption of **[new signature schemes](https://source.android.com/security/apksigning)** as they [held out on the v1 signature scheme](https://forum.f-droid.org/t/why-f-droid-is-still-using-apk-signature-scheme-v1/10602) (which was [horrible](https://www.xda-developers.com/janus-vulnerability-android-apps/) and deprecated since 2017) until they were forced by Android 11 requirements to support the newer v2/v3 schemes (v2 was introduced in Android 7.0). Quite frankly, this is straight-up bad, and **signing APKs with GPG** is no better considering [how bad PGP and its reference implementation GPG are](https://latacora.micro.blog/2019/07/16/the-pgp-problem.html) (even Debian [is trying to move away from it](https://wiki.debian.org/Teams/Apt/Spec/AptSign)). Ideally, F-Droid should fully move on to newer signature schemes, and should completely phase out the legacy signature schemes which are still being used for some apps and metadata.
## 5. Confusing UX
## 6. Confusing UX
It is worth mentioning that their website has (for some reason) always been hosting an [outdated APK of F-Droid](https://forum.f-droid.org/t/why-does-the-f-droid-website-nearly-always-host-an-outdated-f-droid-apk/6234), and this is still the case today, leading to many users wondering why they can't install F-Droid on their secondary user profile (due to the downgrade prevention enforced by Android). "Stability" seems to be the main reason mentioned on their part, which doesn't make sense: either your version isn't ready to be published in a stable channel, or it is and new users should be able to access it easily.
F-Droid should enforce the approach of prefixing the package name of their alternate builds with `org.f-droid` for instance (or add a `.fdroid` suffix as some already have). Building and signing while **reusing the package name** ([application ID](https://developer.android.com/studio/build/configure-app-module)) is bad practice as it causes **signature verification errors** when some users try to update/install these apps from other sources, even directly from the developer. That is again due to the security model of Android which enforces a signature check when installing app updates (or installing them again in a secondary user profile). Note that this is going to be an issue with Play App Signing as well, and developers are encouraged to follow this approach should they intend to distribute their apps through different distribution channels.
This results in a confusing user experience where it's hard to keep track of who signs each app, and from which repository the app should be downloaded or updated.
## 6. Misleading permissions approach
## 7. Misleading permissions approach
F-Droid shows a list of the [low-level permissions](https://developer.android.com/reference/android/Manifest.permission) for each app: these low-level permissions are usually grouped in the standard high-level permissions (Location, Microphone, Camera, etc.) and special toggles (nearby Wi-Fi networks, Bluetooth devices, etc.) that are explicitly based on a type of sensitive data. While showing a list of low-level permissions could be useful information for a developer, it's often a **misleading** and inaccurate approach for the end-user. Since Android 6, apps have to [request the standard permissions at runtime](https://developer.android.com/guide/topics/permissions/overview#runtime) and do not get them simply by being installed, so showing all the "under the hood" permissions without proper context is not useful and makes the permission model unnecessarily confusing.
F-Droid claims that these low-level permissions are relevant because they support Android 5.1+, meaning they support very outdated versions of Android where apps could have [install-time permissions](https://source.android.com/devices/tech/config/runtime_perms). Anyway, if a technical user wants to see all the manifest permissions for some reason, then they can access the app manifest pretty easily (in fact, exposing the raw manifest would be less misleading). But this is already beyond the scope of this article because anyone who cares about privacy and security wouldn't run a 8 years old version of Android that has not received security updates for years.