feather-wallet / feather

A free and open-source Monero desktop wallet.
https://featherwallet.org
BSD 3-Clause "New" or "Revised" License
302 stars 49 forks source link

Flatpak app #47

Closed r3nor closed 3 months ago

r3nor commented 1 year ago

It would be great to offer the app as a Flatpak package (along with current AppImage) and make it available on Flathub.

Thank you for maintaining such a wonderful wallet!

TobTobXX commented 1 year ago

I don't know if this is actually desired by the devs (pls tell me if not), but I have some prior experience working with flatpaks and could write all the required configs.

One thing that will likely not work out of the box is hardware wallets. Since I don't have one, I can't test it and help develop the integration. I can try some blind shots, but if someone could help with that, it'd be helpful.

TobTobXX commented 1 year ago

Also, one question to the developers:

It is desired for flatpaks to be built from source in an offline environment. I'd just reimplement some parts of the Dockerfile (some libraries, like QT and possibly others, are already built and shipped by so-called 'runtimes').

However, if you are really against this (because you want to maintain your own build pipeline or whatever), then please annotate that too. A flatpak could be created by fetching the assets from the website. This is generally discouraged, but possible.

Approach 1 leads to more maintanance if the dependencies change a lot. Approach 2 requires some chore PR-merging each release and possibly some manual URL adjustments.

TobTobXX commented 1 year ago

Ok, so I've done some groundwork on packaging. It now compiles and starts, but still has tons of issues, notably, there is no tor proxy embedded: https://github.com/TobTobXX/org.featherwallet.Feather/tree/org.featherwallet.Feather

maltfield commented 1 year ago

Actually, I'd advise against using flatpak because it's not clear if it's actually secure.

We know for a fact that installing software with apt on Debian-based systems includes cryptographic verification of the authenticity and integrity of the payload that it downloads before it installs any and all software on your machine by default (this is clearly documented in the apt-secure(8) manpage):

And we know that the Feather team signs their releases with a PGP key whoose fingerprint is available from multiple, distinct domains out-of-band. This allows users to verify the authenticity and integrity of the Feather .AppImage release after downloading it & before installing it:

However, it is not clear if flatpak requires any form of cryptographic authenticity and integrity verifications for all the software packages that it downloads before installing them:

Until flatpak's default config requires a valid cryptographic signature for all packages that it downloads before install, I'd advise Feather stay away from a flatpak release.

TobTobXX commented 1 year ago

Uhm... I don't choose Flatpak because of security, but rather because of ease of organization: It keeps applications from littering my home dir. And if you're afraid you're downloading malware because you're getting it from flathub.com, then you can rejoice to have a 100% reproducible build recipe thanks to the flatpak manifest. If you wish so, you can build it yourself and verify the integrity this way.

maltfield commented 1 year ago

@TobTobXX the risk we're trying to mitigate with cryptographic signing of payloads is compromised publishing infrastructure, MITM attacks due to flaws in X.509, and other supply chain compromises

Remember: monero's release infrastructure has already been comprimised once. And here's a great list of historically relevant cases where this happened:

I don't think it would be wise for something as security-critical as Feather Wallet to support flatpak as a release channel because of the associated risk to its users

vorot93 commented 1 year ago

I have updated the @TobTobXX's work here: https://github.com/vorot93/org.featherwallet.Feather/tree/org.featherwallet.Feather

@maltfield Flatpak package is required to use Feather in immutable settings like Fedora Silverblue or openSUSE MicroOS. If you have a problem with Flathub, you are of course free to build your own - leaving OSTree users in the dust just because Flatpak is not perfect is hardly a viable option really. If we go by that logic, Feather shouldn't be available for macOS or Windows either as these are proprietary unsecure platforms full of hidden backdoors.

adapt-L commented 1 year ago

I don't know why github.com has CC'd me on this, but I concur with @maltfield about the limitations of flatpak. I would suggest packaging it for your own distro's package manager instead.

Firstly, It's no secret that most linux distros are highly similar. What sets them apart is the distributor. Fedora users implicitly trust redhat, Debian users implicitly trust the debian community, etc. to review the code, backport vulnerabilities, and to not conduct MITM attacks. Solutions like Flatpak and Snap are roping in an unnecessary third party that breaks this security model. Distributing packages is the primary role of the distributor, so what is Flatpak if not a distribution? You might as well just have everyone run a debian chroot for binary compatibility, it would be a lot simpler!

Furthermore, the containerization is a front to encourage the use of proprietary software on linux. Imagine if Flatpak becomes the mainstream method of distributing packages: that makes the linux ecosystem a lot harder for niche architectures like riscv or ppc64 or different libcs like musl: environments that are only possible in the linux world because of the emphasis on source compatibility. If you want binary compatibility so much, maybe you should just stick to windows or some other userspace that is saddled with decades of technical debt from maintaining binary reverse-compatibility. The lack of binary compatibility is not a bug, is an intentional feature that allows developers to depreciate parts of the ABI. If it is inconvenient for distribute binaries across systems, then that is good. The alternative is passing the inconvenience onto the user.

After spectre and meltdown, I don't know anyone who seriously trusts the OS security model any more, regardless of what containerization gimmicks are involved. The way to prevent malicious programs from breaking the system is to not compile them in the first place. Distributing a program as a binary like this increases the distance between the source code and the user. How would you even go about verifying that a binary is non-malicious unless the binary coheres to some form that enables sufficient static analysis? And that just concerns attacks that require escalation. For most desktop users, simply reading the user's home directory and phoning home is sufficient enough. Even if you can't read the user's home dir,, a cryptocurrency wallet must necessarily have access to the user's private key and the internet, which is sufficient for a crypto-robbery.

At least static compilation does this in a discreet and straightforward way.

Flatpak package is required to use Feather in immutable settings like Fedora Silverblue or openSUSE MicroOS

Do these distros not have conventional package managers you can port it to?

If we go by that logic, Feather shouldn't be available for macOS or Windows either as these are proprietary unsecure platforms full of hidden backdoors.

It is true to some extent that porting security-sensitive software to macOS or Windows is a fruitless effort. But you have to balance the pros and cons. Flatpak makes installing packages slightly easier for new linux users who would be better off in the long run learning how to install packages properly. I am not some sort of security IT professional. I don't know what the ideal containerization method is, but it probably doesn't involve downloading unsigned binaries off the internet and running an entire userspace for every user-facing application.

vorot93 commented 1 year ago

@adapt-L To be frank, I don't give a damn if Flatpak enables, disables, maims or does whatever to proprietary software. It allows neat integration of open source desktop apps into immutable distros and unlike most (all?) packaging systems gives isolation. If you don't like Flatpak, feel free to ignore this issue, of course.

maltfield commented 1 year ago

It might be a good idea for the Feather Wallet devs to update the documentation warning users not to install the software from Flatpak due to the security concerns listed above.

vorot93 commented 1 year ago

Flatpak package has been published on Flathub.

TobTobXX commented 1 year ago

@vorot93 Wow, you were quick! Thanks for doing the dirty work. I hope my initial efforts were at least of some use. Sorry for abandoning this issue...

I'll subscribe to it and will (at least attempt to) give a helping hand when needed on maintaining it. Is there any issue I could help with right now?

Thank you for your work! You just made Monero more accessible for a lot of people.

tobtoht commented 11 months ago

This issue is long overdue for an official response.

I wrote a long post that goes on a lot of tangents, so to quickly summarize my findings; for the purpose of distributing cryptocurrency software: Flathub bad. Flatpak as intended: not good. Flatpak with some modifications: could be great.

For the fate of the unofficial Flatpak, scroll down to the bottom.

What's bad

A few key misses.

All Flatpaks depend on a runtime

It is not currently possible for a Flatpak application to specify that is uses no runtime.

Runtimes are mounted to /usr and applications are mounted to /app inside the container. Flatpak itself mounts some extra files like devices and system fonts depending on how the Flatpak is configured.

Standard runtimes include a wide variety of binaries and system libraries (including bash, coreutils, a python interpreter, ssh, etc). The KDE runtime weighs in at over 2 GB (660 MB compressed) and itself depends on the Freedesktop runtime which is another 200 MB compressed.

Runtimes can be updated independently of the application and are maintained independently of Flatpak. This raises some important concerns about software supply chain security and container security.

It is possible to steal cryptocurrency from users if an attacker manages to (stealthily) introduce malicious payloads into certain files in the runtime. The more users, the higher the bounty. This is pretty unique to cryptocurrency software - no other software class has such a direct financial incentive for threat actors to compromise release infrastructure.

I won't go over how one might set out to do that, but I will tell you that users are putting a lot of trust in the current and future maintainers of the runtime(s) and the libraries it includes, their release infrastructure, and review process.

(Note: the same applies to regular Linux distributions. Though I would argue that big distros like Debian benefit from a lot from more scrutiny. Besides, Flatpak runtimes add trust requirements on top of the trust you already lend to your distribution as was pointed out earlier in this thread. Flatpak being distribution agnostic could lead to a plurality of an application's users using Flatpak which adds further incentives.)

We can't easily prevent all cases in which our application might load or parse files from /usr, even if all libraries are statically linked (which it is not the case), so there is a potential pathway to payload execution. Dependencies might load shared objects from here under certain conditions or read files like fonts and certificates.

Runtimes can also manipulate environment variables which can alter application behavior, although these are listed in the manifest so any tampering here would be noticed quickly. And there might be other ways for runtimes to manipulate the container environment.

It's also generally not a good idea to have shells, coreutils and networking tools available inside a container (if you can avoid it) as this could aid potential secret key or wallet data exfiltration (e.g. via a RCE that is exploitable by malicious remote nodes). This might not stop a sophisticated remote attacker, but having those tools available certainly lowers the bar (should such a vulnerability exist). It also makes payloads in supply chain attacks easier to obfuscate because an attacker can rely on the presence of these tools.

We don't need a standard runtime. All but a few of our dependencies are statically linked (for good reason [1]), which means we are already responsible for the security of our dependencies and have to make sure they stay up-to-date and patched. Runtime dependencies can be bundled in a different way (more on that later). A standard runtime simply adds no value, while massively increasing the attack surface.

Flathub does not allow us to sign our commits

Commits in the Flathub repository are signed with a single GPG key (Flathub's release key). While Flatpak does verify that applications are signed with the key associated with the repository, there is no way for users to verify that the application was signed with our release signing key during installation. Which means you fully trust Flathub's release infrastructure and the people that manage it.

This appears to be a limitation of OSTree (which Flatpak uses under the hood), which does not allow pinning a GPG key to an individual branch. My understanding is that a signature from any of the GPG keys associated with the repository is sufficient to allow an installation or update to proceed. So all third-party Flatpak repositories have this problem.

In theory, it could be possible to verify the installation manually by comparing the checked-out OSTree repository against a signed list of file hashes. But the installation instructions would be so complicated that most users would simply skip this. It would also have to be done on every update. So this is not practical at all.

Flathub allows projects to upload their own builds (however, I was not able to find any supporting documentation on this), but without the ability to sign commits with our release signing key this is entirely pointless.

What's good

Flatpak applications are sandboxed (to a lesser extent, depending on configuration). Flatpak uses bubblewrap to construct sandbox environments. Default permissions can be granted based on the principle of least privilege. Permissions can be further tightened by users; it is trivial to disable or restrict access to the network, file systems, devices, dbus, sockets, etc. This gives users with specific threat models more freedom to restrict what Feather does than might be natively supported.

Users can also protect themselves against application bugs if their threat model calls for it. It's not unthinkable that a programming oversight could lead to undesired behavior that can harm privacy. For example: A user may feel safer starting a Flatpak with --unshare=network rather than relying on Feather's built-in "offline mode" (even if offline mode is correctly implemented). While a similar effect could be achieved with a standalone tool like Firejail or using a different operating system, it's easier to add documentation for a tool the user already has.

As was previously discussed, commits in Flatpak remotes can be signed with GPG. Flatpak will refuse to install an update if it is not signed with key that was initially imported when the remote was added. The GPG key can be authenticated immediately after a remote is added (achieving TOFU).

Flatpak automatically installs a .desktop file, making it so that users can find the application easily and don't have to use the terminal to start it or navigate to a binary with their file explorer or copy it to a root-owned directory manually.

A recent DNS leak that affected official Monero wallets and some downstream projects (but not Feather (we got lucky)) once again highlights the need for better testing.

For example: testing that no network requests are made until the user has granted permission or that the application doesn't write outside of the of the portable directory in portable mode. This makes refactoring code and upgrading third-party dependencies safer, and also gives a better overview of the specific application behavior guarantees that we're trying to make.

The application runs predictably across all major Linux distributions and only has to be packaged once. I probably don't have to explain why that is a nice property to have for maintainers (me) and people answering support queries (also me, though I will give credit to the helpful folks in the support channels).

Flatpak has a concept called extensions that would allow us to easily ship plugins. This is just an idea at this point, but it's something I would like to explore in the future. Non-essential or 'heavier' features like mining, atomic swaps or daemon integration could become add-on features that are optionally installed alongside Feather. This allows us to keep the default application minimal, small and free of third-party or controversial integrations while at the same time offering an easy way to extend functionality for interested users.

How to mitigate the bad

We can host our own Flatpak remote. Users can add Flatpak remotes with a single command.

All commits in our repository are signed with our release signing key. The release signing key never leaves the offline signing machine, a local copy of the OSTree repository is signed, transferred, and rsync'ed to our hosting provider.

We instruct users to authenticate the GPG key associated with the remote in the installation guide. With Flatpak, this is actually simpler than the verification instructions for normal release binaries. It's possible for Flatpak to further streamline this UX, and I have opened an issue in the Flatpak repository for that here.

While it's not possible to specify that the Flatpak uses no runtime, it is possible to have the application use a trivially verifiable empty runtime.

A minimal set of runtime dependencies is bundled with the application. That means: no shells, no coreutils. Essentially just glibc, locales, fontconfig and X.509 certificates. Anything that is absolutely necessary to get the application to run.

The entire Flatpak build directory output must be bootstrappable. Our current release binaries have this guarantee, so our Flatpaks should too.

Build process

The flatpak build dir for Feather is bit-for-bit reproducible and bootstrappable. It is constructed without Flatpak tooling.

build
├── export
│   └── share
│       └── <contrib/flatpak/share>
├── files
│   ├── gnu
│   │   └── store
│   │       └── <guix packages>
│   ├── share
│   │   └── <contrib/flatpak/share>
│   ├── feather
│   └── startup
└── metadata

The total extracted size of our Flatpak is 76.5 MB. Of which 61.9 MB (81%) is the Feather binary itself.

The compressed (download) size is 29.6 MB, which is slightly larger than our AppImages.

Installation process

See: https://docs.featherwallet.org/guides/linux#flatpak-beta

Note: the Flatpak currently hosted on our remote was an earlier pre-optimization demo and is larger than is stated above.

[1] Static linking

Note: The same arguments above can be made for bundling dynamically linked binaries. Static linking does enjoy additional binary size benefits.

The fate of the unofficial Flatpak

Considering that the unofficial Flatpak on Flathub,

I will request to have it removed. This probably won't happen until the official Flatpak has been battle-tested.

If any of the maintainers have any concerns or comments about this, please feel free to share them.

The only way I can see Feather being re-added to Flathub in the future is if it becomes possible for repositories to pin an application to a specific GPG key and easily allow users to authenticate that key.

vorot93 commented 11 months ago

Thank you for the detailed writeup.

This is a sensible position. While hosting on Flathub improves discoverability of Feather, lack of control over publishing chain is a valid point.

At the end of the day, to me it doesn't matter which Flatpak repo hosts Feather, as long as Flatpak in general remains an option.

razzeee commented 11 months ago

Flathub allows projects to upload their own builds (however, I was not able to find any supporting documentation on this)

Right now, this is a manual process, so flathub stuff has to create keys, encrypt them and send them to the other party. Because this doesn't scale, it is only available to a few apps (from the top of my head OBS, Firefox and Thunderbird).

The process is being automated right now, to hopefully allow everyone to upload builds, if they so choose.

tobtoht commented 11 months ago

@razzeee @jameswestman

to hopefully allow everyone to upload builds, if they so choose.

It looks like commits are rewritten to update the appstream file and the developer's signature is lost.

Do developers get a chance to re-sign the commit (after inspecting the changes) before the application is published on Flathub? I couldn't find any developer signatures on OBS / Firefox / Thunderbird, so I'm assuming this is not supported.

It would be great if end-users could verify that an application was signed by both Flathub and the application's developers.

maltfield commented 11 months ago

@tobtoht thanks for weighing-in

Flatpak remotes can be signed with GPG. Flatpak will refuse to install an update if it is not signed with key that was initially imported when the remote was added. The GPG key can be authenticated immediately after a remote is added (achieving TOFU).

I've found the documentation around flatpak and authentication to be exceedingly limiting. Do you know:

  1. How can I configure flatpak to refuse to install any software that's not cryptographcically signed?
  2. What command I can run to figure-out the PGP key fingerprint that's used to sign a given software package?
  3. How can I provide flatpak the PGP public key after my own 3TOFU (confirming the key's fingerprint across three distinct domains for less vulnerable TOFU) for a specific package (ie equivalent of apt-key)?
  4. Where are the rest of the commands documented for investigating the state of authenticity checks on flatpak packages?
tobtoht commented 11 months ago

@maltfield

Answering your questions directly got a bit confusing, so I'll try to present what I know in a way that covers your questions.


Flatpak enables GPG verification by default for all remotes. If you want to add a remote without GPG verification you need to explicitly pass --no-gpg-verify when adding the remote. flatpak remotes will show no-gpg-verify for remotes that are not GPG verified. I'm not sure if Flatpak can be configured globally to disallow such remotes, but you can of course avoid adding any.

Flatpak uses OSTree under the hood to manage remotes. OSTree is responsible for GPG verification. Each remote has a trusted keyring that is used to verify commits for that remote. Some GPG related information is not available from the flatpak command, so in some places we have to use ostree directly.


To add a new remote and authenticate the GPG key(s), two approaches are possible:

(1) Obtain the repository's public key and perform xTOFU. Then, add the Flatpak remote:

flatpak remote-add --gpg-import=/path/to/key.gpg myrepo myrepo.org/repo

The imported GPG key will be added to the trusted keyring for that remote. It is stored in a file called <remotename>.trustedkeys.gpg in the Flatpak repo (typically /var/lib/flatpak/repo).

(2) Import the Flatpak remote using a .flatpakrepo file, which includes the GPG key:

flatpak remote-add myrepo myrepo.org/myrepo.flatpakrepo

The GPG key from the .flatpakrepo is added to the trusted keyring for the remote.

To display the fingerprint of the key that was imported:

ostree remote --repo=/var/lib/flatpak/repo gpg-list-keys flathub

Then confirm the key's fingerprint across multiple distinct domains. If the fingerprint doesn't match, delete the remote (and report this incident to the developers).

Note: From a UX perspective, I believe the second approach is better for new users as it does not involve manually downloading the public key. The key is in the .flatpakrepo should be correct unless there is a compromise. UX can be further improved if Flathub were to show the fingerprints of imported keys when a remote is added.


To find out which keys are in a remote's trusted keyring, use the command from the second approach in the previous section:

ostree remote --repo=/var/lib/flatpak/repo gpg-list-keys flathub

Flatpak uses libostree, so the ostree command might not be installed if Flatpak is installed.

Alternatively, use gpg:

gpg --show-keys --with-fingerprint /var/lib/flatpak/repo/flathub.trustedkeys.gpg

In both cases rename flathub with the name of the remote.


To find out which keys were used to sign a package ("ref"):

$ ostree --repo=/var/lib/flatpak/repo show flathub:app/org.mozilla.Thunderbird/x86_64/stable
commit ccdf793a40c998eb64f7fa431b7331114920888e84e3c1c640492a2a9854ec82
Parent:  3c04bcc9b87caa7c4ef6cc19fb948ae409c2ba30d4b658ea4dc5cfe3bb413f88
ContentChecksum:  d2e618d55dffe025491f372deb34533ea7fb458c5ba5c0b2162071b1dbcd97ad
Date:  2023-07-26 12:12:57 +0000

    Export org.mozilla.Thunderbird

    Name: org.mozilla.Thunderbird
    Arch: x86_64
    Branch: stable
    Built with: Flatpak 1.14.4

Found 1 signature:

  Signature made Wed 26 Jul 2023 02:13:57 PM CEST using RSA key ID 562702E9E3ED7EE8
  Good signature from "Flathub Repo Signing Key <flathub@flathub.org>"
  Primary key ID 4184DD4D907A7CAE
  Key expires Mon 14 Jun 2027 03:19:40 PM CEST
  Primary key expires Mon 14 Jun 2027 03:18:56 PM CEST

A package is a "ref" (in this example flathub:app/org.mozilla.Thunderbird/x86_64/stable) to a particular commit. Commits can have multiple signatures.

To list all installed refs use: ostree --repo=/var/lib/flatpak/repo refs.


To verify a pull (i.e. to update or install a package), OSTree requires at least one signature from the remote's trusted keyring. (See gpg-verify here)

Documentation on gpg verification for OSTree is a bit scarce, but I found the tests (see e.g. here and here) somewhat helpful in understanding how it behaves.

OSTree does not (as far as I'm aware) allow you to assign a trusted keyring on per-ref basis. Verification only happens on a per-remote basis. One can't (again, afaik) configure OSTree such that ref x must be signed with key y AND z.

tobtoht commented 11 months ago

Users can add Flatpak remotes with a single command.

We can do better.

flatpak install --from https://featherwallet.org

Adds the remote and installs Feather in one step. Verification can be done after installation. This doesn't fundamentally differ from downloading a binary and verifying a signature manually.

The webserver is configured to return a .flatpakref on the base URL if the user agent matches ^Flatpak (yes, exactly).


Hot take. Perfect installation UX would look something like this:

# assume/force `https`, don't require `--from` if what is returned is a `.flatpakref`
# or look in a `.well-known` directory by default
# get rid of reverse DNS for application naming while we're at it

$ flatpak install featherwallet.org feather

Found remote `featherwallet.org` with:

GPG fingerprint : 8185 E158 A333 30C7 FD61 BC0D 1F76 E155 CEFB A71C
Location        : https://featherwallet.org/flatpak  

Do you want to add the remote? [Y/n]:

Do you want to install 'feather' from 'featherwallet.org'? [Y/n]: 
chaserene commented 4 months ago

correct me if I'm wrong, but judging by https://docs.featherwallet.org/guides/linux#flatpak, a flatpak from Feather's own remote is available, so this can be closed. (there is also the one on Flathub, which is not updated, I believe due to the above security concerns with Flathub's infrastructure.)

tobtoht commented 4 months ago

Yes, the official Flatpak has been out for a few release cycles and there are no outstanding issues (that I'm aware of).

I'm keeping this open for now as a reminder to request the one on Flathub be removed (soon).