Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <Z42Y1FjRnsbw5GZD@nihonium>
Date: Mon, 20 Jan 2025 01:29:08 +0100
From: Fay Stegerman <flx@...usk.net>
To: oss-security@...ts.openwall.com
Subject: fdroidserver AllowedAPKSigningKeys certificate pinning fundamentally
 unreliable

Hi!

Another update for [1,2,3], still published at [4]: another PoC (bringing
the total to 6) and a lot of new background information.  I've attached the
new and updated files and included the new sections from the README with the
updates below.

- Fay

[1] https://www.openwall.com/lists/oss-security/2024/04/08/8
[2] https://www.openwall.com/lists/oss-security/2024/04/20/3
[3] https://www.openwall.com/lists/oss-security/2025/01/03/1
[4] https://github.com/obfusk/fdroid-fakesigner-poc

============================================================================

# F-Droid Fake Signer PoC

PoC for fdroidserver AllowedAPKSigningKeys certificate pinning bypass.

Published: 2024-04-08; updated: 2024-04-14, 2024-04-20, 2024-12-30,
2025-01-06, 2025-01-08, 2025-01-09, 2025-01-10, 2025-01-19.

NB: no new updates will be provided solely to correct any further
counterfactual statements by F-Droid.  We implore them to take
responsibility for their mistakes instead of spreading misinformation in
order to downplay our findings.

NB: see also OVERVIEW.md.

[...]

### [Observations] Update (2025-01-06)

F-Droid claims that the latest vulnerability "does not affect the repository
on f-droid.org".  Which suggests that they do not understand the
significance of this certificate pinning bypass, or they do not believe
certificate pinning is meant to provide protection against a compromise of
an upstream repository without a compromise of the upstream signing key.
Both are worrying.

All of the vulnerabilities described here were discovered by us *by
accident*, looking into things like key rotation, signature copying, and
security scans for IzzyOnDroid, not vulnerabilities in fdroidserver.  The
first one was independently discovered and reported a year earlier, and
subsequently ignored.

The latest vulnerability, the incorrect regex, was not something we
specifically predicted.  But we warned F-Droid that their approach to
handling certificate pinning with custom code independent of the signature
verification using apksigner was full of mistakes and fundamentally flawed,
which proved to be correct again and again.

We recommended "using the official apksig library (used by apksigner) to
both verify APK signatures and return the first signer's certificate to
avoid these kind of implementation inconsistencies and thus further
vulnerabilities like this one".  We even provided a Python implementation
for that.  All of our recommendations were ignored.  We find this careless
approach to security far more worrying than the impact of the individual
vulnerabilities described here.

We sincerely wish this document didn't have to exist.  We implore F-Droid to
do better, to live up to its potential, and do right by its community.

### [Observations] Update (2025-01-08)

F-Droid now claims PoC 5a is not an "actionable security vulnerability"
because "APKs signed by v1-only are not even installable on latest Android
versions".  This is false.  As long as targetSdk < 30 (and e.g. the official
F-Droid client has 29) they will install just fine.  We even confirmed this
by installing the PoC APK on Android 13-15 just in case, something they
apparently neglected to bother with before making that claim.

### [Observations] Update (2025-01-09)

F-Droid now claims they can't use the patches as-is because of "code quality
issues" (private APIs).  Which applies to exactly one patch: the one they
already merged 8 months ago (fdroidserver.patch).

Because the only way to fix the vulnerability was to monkey-patch androguard
(and an updated version is still not available in Debian, nor has the Debian
stable fdroidserver package received any patches, despite those packages
being maintained by the F-Droid team, so that monkey patch is still needed).

They are also downplaying the impact by insisting these vulnerabilities are
only a problem for third party repositories relying on fdroidserver; which,
even if true, is showing a concerning disregard for the security of the
repositories of other projects relying on fdroidserver.

Again, we find F-Droid's reaction and the security and code review processes
on display here to be highly concerning, far more than the vulnerabilities
we reported.

### [Observations] Update (2025-01-19)

Quoting the response of F-Droid's Technical Lead [12]:

> fdroidserver is fully safe for the tasks it was built for. It has been
> independently audited as well (we have two more audits coming up). If you
> have a trusted collection of APKs, then fdroidserver provides the entry
> point to a trustworthy pipe to the F-Droid client. It cannot protect
> against malicious upstreams, upstreams losing their signing keys, etc. It
> cannot fix the deprecated v1 signatures. Require v2+ signatures, and
> AllowedAPKSigningKeys works with no known weaknesses.

Based on the above, we cannot but conclude that despite earlier claims that
the "goal of AllowedAPKSigningKeys is to make it easy for non-technical
people to manage binary APK repos securely", certificate pinning is in fact
not expected to provide any security against e.g. updates from compromised
upstream repositories as it assumes a "trusted collection of APKs".

We wonder what exactly the intended purpose of certificate pinning is if not
to ensure APKs can only be provided by someone in control of the upstream
signing key, as this is the kind of security repositories like IzzyOnDroid
expected it to provide.  We also observe that the 2018 audit predates the
implementation of AllowedAPKSigningKeys certificate pinning.

Another quote [13]:

> [...] why #fdroidserver implements somethings in #Python rather than
> scraping #apksigner output. Reliably and securely parsing CLI output over
> the long term is really hard to get right because deployed fdroidserver
> code has to be future proof, in that it has to support newer apksigner
> versions that might have changed its output. For example, #fdroidserver is
> coded against apksigner from build-tools version vX.0.0. Someone does `pip
> install fdroidserver`. Then at some point, the user upgrades apksigner to
> version vY.0.0 which breaks the parsing before fdroidserver supports
> apksigner vY.0.0. That breakage needs to fail gracefully, and that is
> really hard to do. Much harder than just writing pure Python code to
> extract the certificates which is tested against the apksigner test suite.
> [...]

We agree that parsing apksigner CLI output would be unreliable.  Which is
why we recommended using the underlying apksig library which has a stable
API and even provided code to do exactly that [14].  This suggestion has
been consistently ignored with zero rationale given, other than clearly
irrelevant objections to parsing CLI output.

We vehemently disagree that the chosen approach of using custom Python code
that does not verify the signatures and relies on matching specific
*behaviour* of specific versions of apksigner (e.g. whether or not and how
it verifies v3.1 signatures) to extract the correct certificates is reliable
or secure.  This is evidenced by the 6th PoC, which works because
fdroidserver completely ignores the APK Signature Scheme v3.1 block (and
does not use any v1 signatures).

We find it concerning that F-Droid constantly chooses to move the goalposts
and continues to rely on a fundamentally broken approach for certificate
pinning, merely patching [15] known vulnerabilities without ever addressing
the underlying cause.

We reiterate once again that we recommended "using the official apksig
library (used by apksigner) to both verify APK signatures and return the
first signer's certificate to avoid these kind of implementation
inconsistencies and thus further vulnerabilities [...]".

Until a proper reliable implementation of certificate pinning using apksig
is provided (if ever), we recommend repositories using AllowedAPKSigningKeys
perform their own audit and assess whether the security they wish to provide
requires performing certificate pinning themselves or switching to e.g.
apkrepotool.

[...]

### [PoC] Update (2025-01-19)

NB: see code comments for requirements.

```bash
$ python3 make-poc-v6.py    # uses app4.apk, adds signing block from fake.apk
$ python3 fdroid.py         # verifies and has fake.apk as signer according to F-Droid
True
43238d512c1e5eb2d6569f4a3afbf5523418b82e0a3ed1552770abb9a9c9ccab
```

[...]

### [Scanner] Update (2025-01-19)

```bash
$ python3 scan.py poc6.apk
'poc6.apk': No v3 certs even though v3.1 cert is present
```

## References

[...]

* [12] https://floss.social/@IzzyOnDroid/113765504171758318
* [13] https://social.librem.one/@eighthave/113820301078034374
* [14] https://gist.github.com/obfusk/cfab950649631c3ece723b9eb277304b
* [15] https://gitlab.com/fdroid/fdroidserver/-/issues/1251

## Links

* https://github.com/obfusk/apksigcopier
* https://github.com/obfusk/apkrepotool

View attachment "OVERVIEW.md" of type "text/markdown" (5993 bytes)

View attachment "make-poc-v6.py" of type "text/x-python" (1550 bytes)

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.