Problem
If KeePassXC is sandboxed in a Flatpak, browsers can only access it, if they are not sandboxed, i.e. installed as an deb/rpm package or similar on the host.
Sandboxing both the browser, i.e. Firefox, and KeePassXC – or at least the browser and installing KeePassXC natively, which you’d actually want for security reasons – is not possible.
TL;DR:
- this should work out-of-the box: Firefox (host-installed), KeePassXC (flatpak from flathub)
- this does not: Firefox (sandboxed), KeePassXC (host or sandboxed, does not matter)
I show a workaround that makes it possible to use both configurations.
This problem is shown in various GitHub issues: flathub/org.keepassxc.KeePassXC#29, keepassxreboot/keepassxc#2656, xhorak/firefox-devedition-flatpak#92, keepassxreboot/keepassxc-browser#297, flathub/org.keepassxc.KeePassXC#13, xhorak/firefox-devedition-flatpak#92, this Bugzilla bug, not to mention the many dupes like keepassxreboot/keepassxc-browser#297, keepassxreboot/keepassxc-browser#276, keepassxreboot/keepassxc-browser#102 etc.
Background
If you just want the solution, you can skip this part. But for the curious, I’ll explain the problems we face:
- KeePassXC creates an UNIX socket in
$XDG_RUNTIME_DIR/kpxc_server
for applications to listen too.keepassxc-proxy
is started – via native messaging – by the browser (triggered by the add-onkeepassxc-browser@keepassxc.org
, i.e. KeePassXC-Browser) and tries to listen on that socket to find messages. - If Firefox is not sandboxed, that proxy can start as usual. The only thing it possibly needs to do is get into the KeePassXC flatpak.
- Flathub KeePassXC has a patch that allows the keepassxc-proxy to be started via
flatpak run
, i.e. Firefox can now run a - That is, so far, why Firefox installed on the host does work…
- Now why it does not work if Firefox is installed as a flatpak: The very good official Firefox flatpak by Mozilla really does have few permissions for being a browser. E.g. it does not have any generic access to the file system (it uses portals). Anyway, whatever it does, it cannot do one thing: Spawn a process on the host or in another flatpak.
So we could solve that by making wrapper scripts and using flatpak-spawn to let Firefox escape it’s sandbox. However, seeing how lovely and quite securley the Firefox sandbox is already built, I would not dare to destroy that security for such a feature. After all, from a security POV you could then also just install Firefox on the host, yet again.
So glad news ahead: This solution preserves all sandboxes and security aspects!
However, even if we’ve solved the fact of Firefox having to run the proxy, there are more problems. To spoiler, this are the main points we need to solve:
- Starting keepassxc-proxy by Firefox (solution: we run it inside the Firefox sandbox)
- Allowing Firefox to access the socket of KeePassXC
Note: At that step, you can already run the variation: Firefox (sandboxed), KeePassXC (host-installed) - Exposing the UNUX socket from the KeePassXC flatpak to other applications outside of the Flatpak. (solution: an symbolic link)
Current workaround
v1.1
Tested with: Fedora 32, org.mozilla.firefox
v75 from flathub, org.keepassxc.KeePassXC
v2.5.4 from flathub
Starting keepassxc-proxy by Firefox
- Worst things first: We need the
keepassxc-proxy
as a binary, because we want to have it run inside of the Firefox flatpak. Good for us: it has not many depenencies and is available as a stand-alone application.- So I chose the Rust proxy application (because why should not I? ). If you trust me, you can get my compiled binary below, just skip to two steps ahead.
- Clone the git repo and compile it (run
cargo build --release
). - You find the result in
./target/release
.
Thekeepassxc-proxy
binary, version211ae91
, compiled with rustc 1.43.0 (the current stable in Fedora 32) for x86_64 (and if it helps and you wanna know more that.rustc_info.json
).
And altghough Rust is not (yet) totally reproducibly compiling I did got the same bit-by-bit result on two machines with Fedora 32. The SHA-256 hash isc5c4c6c011a4d64f7e4dd6c444dcc70bee74d23ffb28c9b65f7ff6d89a8f86ea
.
So if you are in a risky mood, you can just download my keepassxc-proxy binary here. (hosted by GitHub )
- Now we need to tell Firefox about the new binary.
- Go to
~/.var/app/org.mozilla.firefox/.mozilla/native-messaging-hosts
. Actually, thenative-messaging-hosts
likely does not exist yet, so do create it. - Create a file
org.keepassxc.keepassxc_browser.json
in there, and paste in the following content:
Note that only absolute paths work (I guess), so replace{ "allowed_extensions": [ "keepassxc-browser@keepassxc.org" ], "description": "KeePassXC integration with native messaging support, workaround for flatpaked Firefox, see https://is.gd/flatpakFirefoxKPXC", "name": "org.keepassxc.keepassxc_browser", "path": "/home/REPLACE_WITH_USERNAME/.var/app/org.mozilla.firefox/.mozilla/native-messaging-hosts/keepassxc-proxy", "type": "stdio" }
REPLACE_WITH_USERNAME
with your$USER
name, so that the paths leads to it’s own working dir. - You see what I am doing: We now place the downloaded/compiled
keepassxc-proxy
in the same dir. Obviously, you could use any other path there, but this was the first one that is obviously accessible by Firefox and you have everything in one place. (If you have better suggestions, feel free to let me know.)
Note: Remember to make it executable (chmod +x
) if it is not, already.
- Go to
Allowing Firefox to access the socket
KeePassXC, by default, creates it’s socket in $XDG_RUNTIME_DIR/kpxc_server
. So this is what we need to give the Firefox flatpak access to (read-only is obviously enough).
Fortunately, this is easy. Just run:
$ sudo flatpak override --filesystem=xdg-run/kpxc_server:ro org.mozilla.firefox
Hooray!: For those, who install KeePassXC on the host (without any sandbox/flatpak), this is enough. Start KeePassXC and then Firefox and it should be able to connect.
Please note the “existing problems” section at the bottom, though.
Continue, if you also want to run KeePassXC in a flatpak.
Exposing the UNIX socket from the KeePassXC flatpak
Note: Again skip to the bullet point (point 1) below, if you don’t wanna know the technical background.
The flatpaked KeePassXC from Flathub creates it’s Unix socket in the location flatpaks should do so, in $XDG_RUNTIME_DIR/app/org.keepassxc.KeePassXC/kpxc_server
. (If it would use $XDG_RUNTIME_DIR
directly like the “native” KeePassXC, it would only exist in the sandbox.)
As we know, the usual keepassxc-proxy expects the file at $XDG_RUNTIME_DIR/kpxc_server
. To solve this, we just create a symbolic link.
As you can verify, this actually solves our problem. For some very strange reason, the Flatpak sandbox now allows Firefox (and all other flatpaks! Just FYI, be aware of that.) to see that UNIX socket file.
As it should turn out later, this does not work when you move that symbolic link anywhere else (even another file name already prevents it from working – I’ve tried a lot of things.).
However, $XDG_RUNTIME_DIR
is usually deleted at shutdown. So we need to recreate it at startup/user login. Good for us there, is already a tool for that. (you could also mangle with shell scripts in your autostart of course, but that is ugly.)
That’s why we make use of systemd-tmpfiles. (The man page for tmpfiles.d is more useful for us actually.)
- Go to
~/.local/share/user-tmpfiles.d
. Again, there is a high chance theuser-tmpfiles.d
dir does not exist yet. If so… well… you know what to do… - Now download and place the following config file in there: kpxc_server.conf
This is basically a config file forsystemd-tmpfiles
that says it to create that symbolic link for the user. - Reboot, so
systemd-tmpfiles
can apply the changes and create the config file.
Hooray!: Afterwards start the KeePassXC flatpak and then Firefox and it should be able to connect.
Please note the “existing problems” section below.
Existing problems
- Firefox, for some reason, cannot see the
$XDG_RUNTIME_DIR/kpxc_server
file, if the file (respectively it’s symbolic link target) does not exist yet.
In practise, this results in one big disadvantage: You always need to start KeePassXC before Firefox. - For some more strange reason, if you have this workaround setup, the usual way that you run a non-flatpaked native Firefox and connect it by spawning the proxy inside the flatpak (like
flatpak run org.keepassxc.KeePassXC
) may not work. Delete the symbolic link again to make this work.
Debugging tips
- In Firefox use
about:debugging
to access add-on internals.keepassxc-browser@keepassxc.org
is the add-on ID. It actually also logs failed attempts. Note there are different results (logs and visibly) when it cannot start the proxy vs when it can start the proxy, but no connection suceeds (because the UNIX socket is not there, e.g.) - To manually get into the flatpak and “see” in a shell what it has access to/looks like, use something like
flatpak run --command=/bin/sh org.mozilla.firefox
. - To check whether the socket file is accessible (a symbolic link can point to a non-existant file) just
cat
it and you’ll see a strange error thatcat
cannot find a resource
Things I’ve tried
Things that do not work:
Preserved for future solutions and better™ workarounds.
- all things in
$XDG_RUNTIME_DIR/app
are highly sandboxed, even with flatpak overrides I could not get the Firefox flatpak to read the content of the../org.keepassxc.KeePassXC
dir. Even with crazy symbolic links in it’s own dir. (Do try it though, maybe you’ll make it! At least you’ll learn something. .) - what works though is: You can override the KeePassXC flatpak to get access to Mozilla. Only write access possible though! Thus, if it would place the proxy there (again: symbolic links here don’t work!), Firefox could also read it.
- The symbolic link must be created by an application outside of the sandbox. Inside of it, it’s again – sandboxed – and one only visible inside of it.
Final notes
If this helped, feel free to leave me a for this post and/or upvote it on Unix Stackexchange. It took quite some time to figure it out.
I do try to continue improving this workaround and find solutions in this GitHub issue. It’s best to follow there, if you are interested.
I’ve cross-posted this question and answer on Unix Stackexchange and in the Fedora community.