Bubblewrap

From ArchWiki

Bubblewrap is a lightweight sandbox application used by Flatpak and other container tools. It has a small installation footprint and minimal resource requirements. While the package is named bubblewrap, the actual command-line interface is bwrap(1). Notable features include support for cgroup/IPC/mount/network/PID/user/UTS namespaces and seccomp filtering. Note that bubblewrap drops all capabilities within a sandbox and that child tasks cannot gain greater privileges than its parent. Notable feature exclusions include the lack of explicit support for blacklisting/whitelisting file paths.

Warning: Bubblewrap is a tool which provides sandboxing technologies like namespaces and seccomp filter. It does not by default provide a full sandbox that isolates weakpoints like the X11 window system (see #Sandboxing X11). Running untrusted code is never safe, sandboxing cannot change this.

Installation

Install bubblewrap or bubblewrap-gitAUR.

Note:

Configuration

Bubblewrap can be called directly from the command-line and/or within shell scripts as part of a complex wrapper. Unlike applications such as Firejail which automatically set /var and /etc to read-only within the sandbox, Bubblewrap makes no such operating assumptions. It is up to the user to determine which configuration options to pass in accordance to the application being sandboxed. Bubblewrap does not automatically create user namespaces when running with setuid privileges and can accommodate typical environment variables including $HOME and $USER.

It is highly recommended that you download strace to see what files the program you are trying to sandbox needs access to.

Usage examples

Please see /Examples for examples on how bubblewrap can be used. Alternatively, there are various projects that demonstrate how bubblewrap can be used for common applications:

No-op

A no-op bubblewrap invocation is as follows:

$ bwrap --dev-bind / / bash

This will spawn a Bash process which should behave exactly as outside a sandbox in most cases. If a sandboxed program misbehaves, you may want to start from the above no-op invocation, and work your way towards a more secure configuration step-by-step.

Note: This operation will modify all the owner and group to nobody if the owner or group is not the current one, which suggests running some program like sudo will not work properly.

Bash

Create a simple Bash sandbox:

  • Determine available kernel namespaces
$ ls /proc/self/ns 
cgroup  ipc  mnt  net  pid  user uts
Note: The presence of user indicates that the kernel has exposed support for user namespaces with CONFIG_USER_NS=y
  • Bind as read-only the entire host / directory to / in the sandbox
  • Create a new user namespace and set the user ID to 256 and the group ID to 512
$ bwrap --ro-bind / / --unshare-user --uid 256 --gid 512 bash
bash-4.4$ id
uid=256 gid=512 groups=512,65534(nobody)
bash-4.4$ ls -l /usr/bin/bash
-rwxr-xr-x 1 nobody nobody 811752 2017-01-01 04:20 /usr/bin/bash

Troubleshooting

Using X11

Bind mounting the host X11 socket to an alternative X11 socket may not work:

--bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X8 --setenv DISPLAY :8

A workaround is to bind mount the host X11 socket to the same socket within the sandbox:

--bind /tmp/.X11-unix/X0 /tmp/.X11-unix/X0 --setenv DISPLAY :0

Sandboxing X11

While bwrap provides some very nice isolation for sandboxed application, there is an easy escape as long as access to the X11 socket is available. X11 does not include isolation between applications and is completely insecure. The only solution to this is to switch to a wayland compositor with no access to the Xserver from the sandbox.

There are however some workarounds that use xpra or xephyr to run in a new X11 environment. This would work with bwrap as well.

To test X11 isolation, run 'xinput test <id>' where <id> is your keyboard id which you can find with 'xinput list' When run without additional X11 isolation, this will show that any application with X11 access can capture keyboard input of any other application, which is basically what a keylogger would do.

The optimal solution to eliminate the X11 weak point is to switch to a wayland compositor.

Opening URLs from wrapped applications

When a wrapped IRC or email client attempts to open a URL, it will usually attempt to launch a browser process, which will run within the same sandbox as the wrapped application. With a well-wrapped application, this will likely not work. The approach used by Firejail is to give wrapped applications all the privileges of the browser as well, however this implies a good amount of permission creep.

A better solution to this problem is to communicate opened URLs to outside the sandbox. This can be done using snapd-xdg-open as follows:

  1. Install snapd-xdg-open-gitAUR
  2. On your bwrap command line, add:
$ bwrap ... \
  --ro-bind /run/user/$UID/bus /run/user/$UID/bus \
  --ro-bind /usr/lib/snapd-xdg-open/xdg-open /usr/bin/xdg-open \
  --ro-bind /usr/lib/snapd-xdg-open/xdg-open /usr/bin/chromium \
  ...

The /usr/bin/chromium bind is only necessary for programs not using XDG conventions, such as Mozilla Thunderbird.

New session

There is a security issue with TIOCSTI, (CVE-2017-5226) which allows sandbox escape. To prevent this, bubblewrap has introduced the new option '--new-session' which calls setsid(). However, this causes some behavioural issues that are hard to work with in some cases. For instance, it makes shell job control not work for the bwrap command.

It is recommended to use this if possible, but if not the developers recommend that the issue is neutralized in some other way, for instance using SECCOMP, which is what flatpak does: https://github.com/flatpak/flatpak/commit/902fb713990a8f968ea4350c7c2a27ff46f1a6c4

Nested namespaces

Certain applications such as Chromium already implement their own sandbox environment using suid helper files. This mechanism will be blocked when they are executed inside a bubblewrap container.

One solution is to have the application use the namespace created by bubblewrap. This can be achieved through zypakAUR which is also used by flatpak to run electron based apps inside an additional namespace. Example code that demonstrates how to use zypak with Chromium/Electron can be found at [1].

See also