phyto's ramblings

Linux Sandboxing

The state of Sandboxing on Desktop Linux

Or, more rather, how secure can a linux desktop system be without trying too hard.

This post is a summary of my thoughts, and while I strive to keep it accurate, there wil be mistakes here and there! If you are one of the wonderful people who spotted any inaccuracies, please let me know!

Types of sandboxes

Broadly speaking, on linux sandboxing usually involves one or more of these things:

Each of these comes with different tradeoffs, and none of them are inherently better than any others. I won’t be focusing on any particular technology, but instead on specific tools with a focus on usability.

Use Flatpak for desktop apps

Easy, cheap and reasonable

All Flatpak apps are sandboxed by default using bwrap. Unfortunately, some of the apps on flathub (the only flatpak repository anyone cares about) come with really weak policies out of the box. This is something that people have complained loudly about, but it’s not that big of a problem anymore - regardless, you should be aware of it.

Luckily for us, we can tweak them! Flatseal is an utterly invaluble tool for this1. It lets you toggle basically everything under the sun.

Very often, apps will include the filesystem=host or filesystem=home permission, which is basically a free pass to do whatever it wants. In a majority of cases, you should manually disable this and grant specific access to directories (can be read-only or read-write), and it will still work fine. Most apps include this because they don’t (yet) support file choosers, so if opening a file mysteriously shows an empty home directory that’ll be why.

share=network is also a good one to disable when you don’t plan on using the networking capabilities of an app (e.g. a markdown editor with a cloud backup). Just keep in mind that share=ipc (and probably some other permissions) might let it bypass these network permissions by making another program do it for them.

If you use X11, then flatpak is largely worthless to you. X11 just doesn’t play nicely with sandboxing. If you ever hear people talking about how Wayland is “more private” or “more secure”, this is why - sandboxing X11 apps needs workarounds.

Sadly, some kernel interfaces like /sys and /proc aren’t sandboxed by flatpak, and the seccomp policies are weak. Flatpak is not a silver bullet, and it can’t do the things a VM can. Use your discretion and tread lightly.

Web browsers

This is where things get messy. Web browsers are about 200-300MB worth of binary that executes untrusted code from a network, and so obviously both firefox and chromium do a lot to sandbox the websites inside of them.

One of these sandboxes is user namespaces. Flatpak understandably doesn’t let apps create user namespaces because they open up a pretty wide attack surface for the kernel; same story with chroots (which can be used to make sandboxes, but isn’t strong enough to be a sandbox on its own).

For Chromium, this actually isn’t a problem. It uses flatpak APIs that let it achieve roughly equal security.

For Firefox (and the Tor Browser) though, it seems like they work around this problem by just not using the user namespace sandbox at all2. This is certainly… an interesting approach, especially for something approved by Mozilla. To be clear, this doesn’t remove the sandbox layer entirely, it just moves it up from being per-site to per-browser: your browser (inc. tabs, cookies, saved passwords…) becomes much more vulnerable to websites, but your OS becomes slightly less vulnerable to a misbehaving browser. This is still generally considered a bad thing, because you just turned your sandbox from a child’s playpen into an entire beach - the playpen is a lot easier to lock down, and the beach is likely to have secret exits nobody knows about just due to the sheer scale of it. So if at all possible, please just use the natively packaged firefox or tor browser.

Use containers when you can’t get it through flatpak

Hard to learn, but quick, lean and dirty once mastered

“containers” is a broad term that I’m using to refer to anything using namespaces. The namespace is then combined with a seccomp filter to get rid of some easy namespace escapes, put in a chroot (or similar) to limit filesystem access, and then it drops any privellages it might still have.

Ordered from usabile to robust, you get: firejail, containers (e.g. using guix containers), and bwrap. There are probably quite a few more ways that I can’t be bothered to list.

The main one you want to care about3 is bwrap, because it’s the leanest, less likely to get you laughed at by security nerds, and the only one I am familiar with most popular. It is used by flatpak and describes itself as a “helper for container setup” which “you are unlikely to use it directly from the commandline” - but we are gonna do it anyway a bit for fun and profit and pain!

$ bwrap --ro-bind /lib64 /lib64 --ro-bind /bin/sh /bin/sh sh
sh-5.1$ echo hello
hello
sh-5.1$ ls
sh: ls: command not found

Amazing! Keep in mind that this is all from userspace, too! You won’t need 6 root terminals open to debug your awful MAC policies, and they can be changed really easily on the fly. Just be aware that the learning curve takes a hike into the sun, mostly because you now need to handle your own seccomp filters (if you don’t provide one for bwrap, you don’t get seccomp filtering at all, leaving you with quite a weak sandbox).

If you are interested in trying this out more, try starting with these examples on the arch wiki and then, after some experimentation and man 1 bwrap, these much more complicated ones.

Hint: if you get errors like bwrap: execvp sh: No such file or directory, then try --ro-bind /lib64 /lib64 --ro-bind /usr/lib64 /usr/lib64. Also make sure your executable has all the dynamic libraries it needs with ldd(1), like ldd $(which bash) (we use which because it needs the full path to the executable, you could do ldd /bin/bash as well!).

Use MAC when all else fails

Good tooling, and sometimes the best tool for the job

The primary advantage of MAC is that it still lets you integrate programs nicely with your system. You still call the same binary file the same way you always did, and the sandboxing just appears around it (courtesy of the kernel). If you like to build from source, or install through your system’s native package manager, then this is your best bet.

The downside is that you will need to make your own policies! Some distributions will ship base profiles for apparmor or SELinux policies, but these mostly target daemons.

If you can, try to use someone else’s policies before making your own.

For apparmor, this is a good place to start, but the process generaly is just running aa-genprof, running the program and using as many features of it as you normally will, and then running aa-logprof and restarting the program 20 times because you messed something up the first time.

SELinux I’m definitely not qualified to talk about, so wont.

Personally, I use apparmor to sandbox firefox (because the flatpak version isn’t great, and I want the version from my package manager), nheko (because I want the version from my package manager, and can’t be bothered to learn how bwrap works), and a couple of other small CLI programs that touch the network. For this, it works well enough.

MAC isn’t really ideal unless you are dealing with system daemons though.

Conclusion

The ease of use of flatpak means that average linux desktop users can benefit from at least some sandboxing, even if they don’t realise this. Remember that the only reasonable way to sandbox graphical apps is with a VM (hard to setup and swallows almost as much ram as element-desktop), MAC (even harder to setup because you almost always need to roll your own policies), or with a namespace (difficult to make without weak sandboxing or considerable skill)…

…or you could just install the flatpak version of an app.

Flatpak is probably one of the, if not the, biggest advances in linux desktop security in the last few years; it’s almost entirely because it requires relatively little setup. Yes, it exposes a lot of kernel interfaces that might be undesireable, but it’s still a hell of an improvement!

Oh, and MAC and containers also don’t use the portals API, meaning if you want to access a file you need to punch a big-ol hole right in the middle of your sandbox, or move it4. This is quite far behind flatpak, and unlikely to change in the short term.

Or, yknow, just use Qubes and get on with your life.


2023-10-02: Clarified that namespaces alone aren’t everything, and the risk of running firefox in flatpak 2023-10-04: Made firefox tangent more explicit in saying that flatpak’d firefox is bad


  1. Flatseal doesn’t actually do the sandboxing stuff, it just changes the files in ~/.local/share/flatpak/overrides/, but it makes this so easy and approachable that even I, a terminal-dwelling gremlin, honestly prefer it to manually editing the files. ↩︎

  2. There’s not an awful lot of helpful resources online about this, but you can go under about:config and look for “User Namespaces” under the “Sandbox” section, which is the closest thing I could find to an authoritative source. Obviously this might not actually result in any significant weakness on the sandbox, but it’s better to play it safe. ↩︎

  3. Firejail has its own problems and Guix containers will only work with an entire package manager installed. Bwrap is generally considered a safe choice security-wise. ↩︎

  4. By the way, apparmor doesn’t like symlinks and will refuse to follow them. You either need to make a hardlink, or cp the file. ↩︎