[GH-ISSUE #3767] firefox: keepassxc browser extension fails due to whitelist-runuser-common #2375

Closed
opened 2026-05-05 09:03:25 -06:00 by gitea-mirror · 2 comments
Owner

Originally created by @kris7t on GitHub (Nov 22, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3767

Since 096d0de5f8, firefox-common.profile includes whitelist-runuser-common.inc.

This breaks compatibility with the KeePassXC browser plugin, which uses the socket ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer to communicate with KeePassXC (see https://github.com/keepassxreboot/keepassxc/blob/develop/src/browser/BrowserShared.cpp#L30-L37).

The problem here is that the socket might not exist when Firefox starts if KeePassXC hasn't started yet. Additionally, KeePassXC might quit and restart any time during when Firefox is running. So we can't just

whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer
writable-run-user

We can redirect where KeePassXC puts its socket by the environmental variable SNAP_USER_COMMON, but only when it was compiled as a snap (#define KEEPASSXC_DIST_SNAP). So to allow Firefox to communicate with KeePassXC, currently the only solution is

ignore include whitelist-runuser-common.inc

Can we do anything with this? One possible solution is to raise an issue with KeePassXC to make the let the socket location be customized with an environmental variable, and the put the socket to some directory that is allowed inside ${RUNUSER}.

The other, perhaps more general approach I can think of is to watch ${RUNUSER} outside of the sandbox with inotify, and mount new sockets matching a name (if the profile is explicity configured to do so) inside the sandbox, too (and when a socket disappears from outside, also remove it inside the sandbox). However, this seems extremely impractical, as mounting the sockets inside the sandbox would require firejail to maintain root privileges.

Originally created by @kris7t on GitHub (Nov 22, 2020). Original GitHub issue: https://github.com/netblue30/firejail/issues/3767 Since https://github.com/netblue30/firejail/commit/096d0de5f8bb253d0c1035796464bc5982f06f81, `firefox-common.profile` includes `whitelist-runuser-common.inc`. This breaks compatibility with the KeePassXC browser plugin, which uses the socket `${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer` to communicate with KeePassXC (see https://github.com/keepassxreboot/keepassxc/blob/develop/src/browser/BrowserShared.cpp#L30-L37). The problem here is that the socket might not exist when Firefox starts if KeePassXC hasn't started yet. Additionally, KeePassXC might quit and restart any time during when Firefox is running. So we can't just ``` whitelist ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer writable-run-user ``` We can redirect where KeePassXC puts its socket by the environmental variable `SNAP_USER_COMMON`, but only when it was compiled as a snap (`#define KEEPASSXC_DIST_SNAP`). So to allow Firefox to communicate with KeePassXC, currently the only solution is ``` ignore include whitelist-runuser-common.inc ``` Can we do anything with this? One possible solution is to raise an issue with KeePassXC to make the let the socket location be customized with an environmental variable, and the put the socket to some directory that is allowed inside `${RUNUSER}`. The other, perhaps more general approach I can think of is to watch `${RUNUSER}` outside of the sandbox with inotify, and mount new sockets matching a name (if the profile is explicity configured to do so) inside the sandbox, too (and when a socket disappears from outside, also remove it inside the sandbox). However, this seems extremely impractical, as mounting the sockets inside the sandbox would require firejail to maintain root privileges.
Author
Owner

@rusty-snake commented on GitHub (Nov 22, 2020):

KeePassXC was the reason why I did not add wruc initial to firefox because ignore include wasn't supported at this time. Then I stopped to use KPXC-Browser because it looks like it is fingerprintable. Before adding it here to firefox I had some testing, but they changed the socket name, this has destroyed my test I think.

IMHO we should add ignore include whitelist-runuser-common.inc to firefox-common-addons.inc.
UPDATE: I already added it in 096d0de. However a comment would be nice.

Using XDG_RUNTIME_DIR isn't a solution too, since we would need to bind-mount wayland, Xauth, pulse, ....

<!-- gh-comment-id:731716715 --> @rusty-snake commented on GitHub (Nov 22, 2020): KeePassXC was the reason why I did not add wruc initial to firefox because `ignore include` wasn't supported at this time. Then I stopped to use KPXC-Browser because it looks like it is fingerprintable. Before adding it here to firefox I had some testing, but they changed the socket name, this has destroyed my test I think. ~~IMHO we should add `ignore include whitelist-runuser-common.inc` to `firefox-common-addons.inc`.~~ UPDATE: I already added it in 096d0de. However a comment would be nice. Using `XDG_RUNTIME_DIR` isn't a solution too, since we would need to bind-mount wayland, Xauth, pulse, ....
Author
Owner

@kris7t commented on GitHub (Nov 22, 2020):

Maybe we could still manage with a proxy? I.e., run some process in sbox_run that listens on a socket ${TMPDIR}/org.keepassxc.KeePassXC.BrowserServer in the sandbox (if ${RUNUSER} is not writable, KPXC-Browser falls back to ${TMPDIR}). For each incoming connection, the proxy attempts to connect to ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer outside the sandbox by path (and not by an O_PATH fd!) and passess messages is both directions through. Could be

proxy-socket ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer ${TMPDIR}/org.keepassxc.KeePassXC.BrowserServer

to support wruc with sockets in a generic way.

Although even this might not be practical: we must ensure that

  1. The proxy runs with the executing user's privileges, so we don't accidentally expose sockets to the user that they don't have access to otherwise.
  2. The location for the proxy socket inside the sandbox is normally writable by the user (otherwise they could impersonate a daemon with higher privileges inside the sandbox).

For a single communication pathway (KPXC <-> Firefox), it seems easy enough to use $XDG_RUNTIME_DIR by hand: just create a new directory somewhere, bind-mount wayland, pulse before either of KPXC or Firefox starts, then run both of them with $XDG_RUNTIME_DIR set to the new directory. The original /run/user/$UID can be blocked entirely. However, if there are multiple browsers, they'd need to share $XDG_RUNTIME_DIR (which is no worse than what we have without wruc).


Of course, this is all just theoretical: In practice, it's simple and safe enough to ignore include whitelist-runuser-common.inc.

<!-- gh-comment-id:731734398 --> @kris7t commented on GitHub (Nov 22, 2020): Maybe we could still manage with a proxy? I.e., run some process in `sbox_run` that listens on a socket `${TMPDIR}/org.keepassxc.KeePassXC.BrowserServer` in the sandbox (if `${RUNUSER}` is not writable, KPXC-Browser falls back to `${TMPDIR}`). For each incoming connection, the proxy attempts to connect to `${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer` outside the sandbox _by path_ (and not by an `O_PATH` fd!) and passess messages is both directions through. Could be ``` proxy-socket ${RUNUSER}/org.keepassxc.KeePassXC.BrowserServer ${TMPDIR}/org.keepassxc.KeePassXC.BrowserServer ``` to support wruc with sockets in a generic way. Although even this might not be practical: we must ensure that 1. The proxy runs with the executing user's privileges, so we don't accidentally expose sockets to the user that they don't have access to otherwise. 2. The location for the proxy socket inside the sandbox is normally writable by the user (otherwise they could impersonate a daemon with higher privileges inside the sandbox). --- For a single communication pathway (KPXC <-> Firefox), it seems easy enough to use `$XDG_RUNTIME_DIR` by hand: just create a new directory somewhere, bind-mount wayland, pulse before either of KPXC or Firefox starts, then run both of them with `$XDG_RUNTIME_DIR` set to the new directory. The original `/run/user/$UID` can be blocked entirely. However, if there are multiple browsers, they'd need to share `$XDG_RUNTIME_DIR` (which is no worse than what we have without wruc). --- Of course, this is all just theoretical: In practice, it's simple and safe enough to `ignore include whitelist-runuser-common.inc`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#2375
No description provided.