Application Sandboxing
Last updated
Last updated
I was recently thinking about finding mitigations to the lack of application isolation on X11. Applications run by the same user have the capability to "log all keystrokes, tamper with other apps windows, steal the contents of copy/paste buffers, inject keystrokes into other windows, etc"[2]. This led me to look into application sandboxing solutions for Linux. This blog post is my journey testing out sandboxing solutions.
Author's note: This blog post got large really fast. I had to cut down talking about other sandboxing solutions, as I was at 6500+ words discussing only the topic of sandboxing. Due to this, I plan to make MACs (originally planned for this blog post) into another blog post.
In order to test out the solutions, I will be using a virtual machine (VM). I try to spin up a test environment for every project I run, just so I don't make any permanent changes to my system that I cannot undo. There is unfortunately no "undo" button for major changes on an OS. It is similar to how enterprises have test and production environments. With that being said, I have recently switched over to using KVM+QEMU instead of VirtualBox. I made this decision after reading the following page on the Whonix site: which resonated with me. In order to install KVM+QEMU on Ubuntu-based Linux you run:
sudo apt install qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virtinst libvirt-daemon virt-manager -y
This will install the apps and its dependencies. I have a cheatsheet if you want more commands for running machines, etc. I used for this post, and after moving the ISO to /var/lib/libvirt/images/
, I ran the following command to install it:
This command flags or options are self-explanatory, so I didn't choose to spell them out here. After updating and upgrading the OS, I do run sudo apt install openssh*
and sudo ufw allow ssh
on the machine so I can SSH from my own system without having to access the GUI. The initial command (aforementioned in the code box above) should also pop open a screen into the VM as well, allowing you to see and interact with the VM. Here are the usual commands I use to interact with the machine:
List all VMs: virsh list --all
Start PopOS (or VM name): virsh start PopOS
GUI view into a running VM: virt-viewer --connect qemu:///system PopOS
Find IP Address of VM (for SSH): virsh domifaddr --domain PopOS
For shutting down the VM, I have not had success using virsh shutdown PopOS
, so I run either /sbin/shutdown
(user has permission for this) or sudo shutdown now
.
You could also use the GUI application "Virtual Machine Manager" (virt-manager
) to manage your VMs:
On Linux, there are two popular display server (a.k.a windowing system) protocols: X11 and Wayland [6]. Wayland is the more modern display protocol that attempts to deal with GUI Isolation, although I could not locate specific Wayland documentation (from Wayland) that alludes to this being a featured feature. Unfortunately, the open source display server for the X11 windowing system: X.Org Server, does not provide application isolation [3,4,5,6]. This allows malicious apps ran on the X.Org Server to do the following: keylog, screenshot programs, record the screen, mess with other applications, etc. [3,4,5].
Just a small aside for some synonyms for information going forward. X11: X and X Window System X.Org Server: X Server
This is due to how the server is configured. See the following image:
One thing to mention here is that apps that use the flatpak, Snap, etc. packages have their own sandboxing to some aspect. Thus, they might not be **as ** harmful when accessing the X.Org Server compared to apt,dnf,pacman, etc. installed packages.
The following steps I will list below:
As root (sudo su -
) run gedit /root/secret_passwords.txt
Run xinput --list
to see list of peripherals to your PC and note the id of your keyboard. This will not be a pointer device, but a keyboard device (NOTE: If you see multiple options for your keyboard, you might have to play around with it in step 3, to see which one is showing results. The output should say "key press XY" or "key release XY" when you press keys on your keyboard.)
Run xinput test XY
, replacing XY with your id from the previous step
You should see output when you press a key on your keyboard
The values that xinput provides seem to have a shift of 8-9 compared to the output from evtest
(which is accurate):
As such, I wrote the following code to take the input from xinput and convert that to the key pressed:
NOTE: The aforementioned code can modified as a remote keylogger running constantly in the background (using cron) and sending inputs to a remote webhook or C2 server, but that is out of scope of this blog.
Output of the code:
While typing as the root user into a root-readable file, the xinput is able to pickup all of the keyboard presses, since both windows are using the same X.org server.
The user-level user is also able to screenshot the desktop as well, including apps being run by the root user as well. You can run the xwd -display "${DISPLAY}" -root | convert xwd:- screen.png
command as user to test this out [1]:
These are just a couple examples of what this vulnerability can lead to. Now, let's look into Flatpak and Snappy to see how they implement sandboxing.
Flatpak is a package manager that allows for easy installation of apps on Linux. For example, installing Flatpak and a Flatpak application is as easy as the following:
There is no need for a local Markdown application to have access to the network. Just to be sure, I downloaded the app and checked if any aspect of it needed network access...it did not.
In addition, the Flatpak application has access to read all files on the system. This reminds me of an XKCD comic that works well as an example for this:
After running this, you can choose to override the overrides by going on an app-by-app basis and changing what permissions need to be modified [20]:
You could possibly have a bash file that has your flatpak override commands for all your applications in it. Then you can run that in one command with flatpak -y
, as such: sudo apt update -y && sudo apt upgrade -y && flatpak update -y && bash script.sh
. This way the permissions will not be changed across updates automatically, and you are still able to update everything in one run. However, this might be a bit more complicated than just using Flatseal.
These were the main topics I wanted to mention regarding Flatpak applications. Now let's move to see how Snappy deals with sandboxing.
"Ubuntu’s Snappy system, which allows developers to create snap packages that are supposed to run on any system on which the Snappy system can be installed. Each snap application runs in its own isolated sandbox, which helps protect the system from malicious programs. Each snap package is a self-contained unit, which means you don’t have to worry about installing dependencies. You can even create snap packages for servers that contain multiple services. The snapd daemon constantly runs in the background, automatically updating both itself and any installed snap applications." [12]. There are 3 main parts to the Snappy system for a desktop user: the snap application, the snap daemon, and the Snap Store [12,22]. For the sake of this blog, we will only focus on the snap applications and the sandboxing and permissions related to it.
Snap applications use "a combination of AppArmor, seccomp, mount namespaces, cgroups and traditional UNIX permissions. To then allow a package access to common resources, the snap system provides ‘interfaces’ to which packages can be granted access as required or determined by the user" [23]. SECCOMP, or seccomp, "allows a process to make a one-way transition into a "secure" state where it cannot make any system calls except exit(), sigreturn(), read() and write() to already-open file descriptors. Should it attempt any other system calls, the kernel will either just log the event or terminate the process with SIGKILL or SIGSYS. In this sense, it does not virtualize the system's resources but isolates the process from them entirely" [27].
Strict Used by the majority of snaps. Strictly confined snaps run in complete isolation, up to a minimal access level that’s deemed always safe. Consequently, strictly confined snaps can not access files, network, processes or any other system resource without requesting specific access via an interface (see below).
Classic Allows access to the system’s resources in much the same way traditional packages do. To safeguard against abuse, publishing a classic snap requires manual approval, and installation requires the --classic command line argument.
In order to see what confinement is turned on, you have to verify this on an app by app basis. For Postman, it would be: snap info --verbose postman | grep "confinement\|devmode"
[24]. The devmode
is not needed, but it reflected what was in the Ubuntu documentation, so I kept it. The confinement on Ubuntu-based distributions is "strict", while for other distributions it would be "classic" by default [7]. Of course, if you wanted a list of all of them at once, you could run a loop that runs through the list. It would look something along the following:
If you have classic confinement, you will have to modify a kernel permission to get your snap to strict confinement, that being: systemd.unified_cgroup_hierarchy=0
[7]. If you are not using an Ubuntu or one of its derivatives, I would just recommend not using Snappy at all, and instead try to find an alternate way to download the application. You will have better options to sandbox than classic confinement: such as Bubblejail or a MAC like AppArmor or SELinux.
The command line would show you similar information as well. For that you would run snap interfaces application_name
or snap connections application_name
[23,25]. If you wanted to manually append or remove permissions, you can do that with snap connect snap_application:plug_interface
(ex. connecting VLC to the audio-record plug: sudo snap connect vlc:audio-record
) [26]. For the previous example, you would replace "connect" with "disconnect", so sudo snap disconnect vlc:audio-record
[26].
With that being said, that pretty much covers what I wanted to discuss for Snappy. Holistically, the strict confinement is ideal for what I am looking for. However, the non-open-source nature of the distribution method, Snappy application server, make me a bit hesitant to hedge all my bets on Snappy. I plan to use Snappy when other options are not sufficient for me to use, and instead try to use the built-in package manager to download applications.
"Firejail uses namespaces, SECCOMP, and kernel capabilities to run untrusted applications in their own individual sandboxes. This can help prevent data leakage between applications, and it can help prevent malicious programs from damaging your system" [12]. I did define seccomp before for Snap applications, but I will mention a concise summary just as a reminder: It limits the system calls (syscalls) a program can make to only the following: "exit(), sigreturn(), read() and write() to already-open file descriptors" [27]. This prevents the program from getting access to more syscalls then it would need to work. While doing research into this, it seems that Firejail not only uses seccomp, but seccomp-bpf. "seccomp-bpf is an extension to seccomp that allows filtering of system calls using a configurable policy implemented using Berkeley Packet Filter rules" [27,28]. "The Berkeley Packet Filter (BPF; also BSD Packet Filter, classic BPF or cBPF) is a network tap and packet filter which permits computer network packets to be captured and filtered at the operating system level. It provides a raw interface to data link layers, permitting raw link-layer packets to be sent and received, and allows a userspace process to supply a filter program that specifies which packets it wants to receive" [29].
" Xephyr is a nested X server displaying its root window (the desktop) inside an X window; Xpra is the X equivalent of screen or tmux, providing a virtual X environment and the ability to display the desktop or individual application windows locally or remotely, attaching and detaching as necessary.
Xpra can also forward audio, the clipboard and printing services. It provides nested X, but as a subset of everything it can do. "
In addition, the Firejail documentation does mention that Xpra is forwarding X11 applications, while Xephyr is an X server itself [30]. Similar to Sakaki, I do believe that Xephyr is the solution we need for our use.
Straight out of the gate, with Xephyr, we can see a difference in socket name. Running firejail --x11=xephyr --xephyr-screen=854x480 firefox
, we now see a change:
The X130 socket is what Firefox now has access to as well:
In order to prevent privilege escalation from an application, we need two arguments: --caps.drop=all
and --nonewprivs
. The first argument drops all capabilities and "causes subsequent attempts by the process (or its children) to load kernel modules, escalate privileges, replace the kernel, restart the system etc. to be rejected" [1]. The second argument "prevents any privilege escalation via execve; it is automatically set if a seccomp-bpf filter is in use, and for avoidance of doubt is explicitly set by firejail's default firefox profile too" [1].
Combining all of these arguments gets us the following: firejail --x11=xephyr --xephyr-screen=854x480 --net=enp1s0 --caps.drop=all --nonewprivs application_name
. Running a version of this command showed an error:
You can spend hours building specific profiles per application. For Firefox, I was able to find a reasonable command online: firejail --noprofile --nogroups --private=~/firejail/ --private-dev --private-tmp --ipc-namespace --machine-id --noroot --caps.drop=all --seccomp --debug --trace --nosound --no3d firefox --new-instance
[33]. This does the following:
Overall, Firejail is a pretty good tool to use for sandboxing and does allow one to customize it pretty well. However, if I can find an alternate in Bubblewrap, which is not using SUID to work, that would be ideal for me.
Bubblewrap is a bit limited in terms of what it can sandbox and what it cannot. On the GitHub page, they mention: "Firejail knows about Pulseaudio, whereas bubblewrap does not" (Pulseaudio is a audio server on Linux) [35]. Bubblewrap also has the main namespaces as features for users to use as well [35]:
Let's jump into how to create a command/script/profile for each application we plan to sandbox. The Bubblewrap documentation was pretty dry for me, so I was able to piece together what I needed from the following sources, which I will mainly reference going forward (I will cite other sources if I use them, but not the following for this section going forward):
I started off by giving the app read-only permission on my system. In addition, clear out the environment variables (this leaks information about your configuration and system - we can add variables as needed):
bwrap --ro-bind / / --clearenv bash
We can see this working already:
We can then change the local /tmp directory to be the $HOME directory of the sandboxed application:
bwrap --ro-bind / / --bind /tmp $HOME --clearenv bash
NOTE: If you get the bwrap: execvp bash: No such file or directory
error, you will have to run ldd $(which bash)
(replace bash with application name) to find out the libraries that bash uses. From there, you can "import" those libraries into the bubblewrap command (ex. bwrap --ro-bind /usr /usr --ro-bind /bin /bin --ro-bind /lib /lib --ro-bind /lib64 /lib64 --ro-bind /sbin /sbin --ro-bind /etc /etc bash
).
Let's unshare the user and unshare the network:
bwrap --ro-bind / / --bind /tmp $HOME --clearenv --unshare-net --unshare-user bash
For some reason the network was unshared, but the user was not shared initially anyway, thus no "unshare". I kept this command either way.
We can add a hostname here as well. This can prevent us "leaking" the Operating system we are using:
bwrap --ro-bind / / --bind /tmp $HOME --clearenv --unshare-net --unshare-user --hostname hostname --unshare-uts bash
The --hostname
parameter needs --unshare-uts
to work, so that was added as well.
Finally, lets add the following:
a devtmpfs file system (--dev /dev
)
temporary /var folder (--tmpfs /var
)
an isolated /proc folder for processed (--proc /proc
)
temporary $HOME (--tmpfs $HOME
)
unshare PIDs so sandbox can't see apps outside of sandbox (--unshare-pid
)
Adding all this, we have the following:
We can convert this into a script to make it easy to make changes and to use as a default "profile" when using other applications with Bubblewrap as well. This is easily done by adding a \
after each parameter:
The "$@" at the end refers to the command and its arguments. If you just wanted to get the command only, then it would be "$1".
After trying to play around and create profiles for both Firejail and Bubblewrap, I understood the difficulty in creating a custom profile. In order to do this, you need to learn about D-Bus, and also have knowledge about X11 vs. Wayland, PCI devices, etc. In addition, in order to make sure the permissions are not too granular or too permissive you have to read each line to make sure it is perfect for your use case. Even with firejail --build=application_name.profile application
, you have a profile which is not usable out of the gate. Using the output of syslog and other system log files, and then appending to a firejail/Bubblewrap profile, is not ideal in my opinion for even technical users. To clarify, I am not asking for a perfect out of the box software; I am just asking for a solution that makes sandboxing just a bit easier to understand and maintain out of the box.
I need to switch to Wayland to mitigate the X11 vulnerability, as the sandboxing solutions did not pan out as expected
I need to run flatpak update
instead of flatpak update -y
to make sure I do not override any past permissions
While downloading a new Flatpak or Snappy app, I need to be cognizant of what permissions I allow it to have
Firejail and Bubblewrap (and even Bubblejail) need a lot of maintenance to create profiles. Doing this for every single application using these tools is not ideal
https://wiki.gentoo.org/wiki/User:Sakaki/Sakaki's_EFI_Install_Guide/Sandboxing_the_Firefox_Browser_with_Firejail
https://security.stackexchange.com/questions/3589/passive-and-active-attacks-via-x11-is-wayland-any-better
https://en.wikipedia.org/wiki/X.Org_Server
https://theinvisiblethings.blogspot.com/2010/08/ms-dos-security-model.html
https://madaidans-insecurities.github.io/guides/linux-hardening.html
https://unix.stackexchange.com/questions/345344/difference-between-xorg-and-gnome-kde-xfce
https://privsec.dev/posts/linux/desktop-linux-hardening/
https://www.flatpak.org/setup/Debian
https://docs.flatpak.org/en/latest/introduction.html
https://docs.flatpak.org/en/latest/under-the-hood.html
https://github.com/containers/bubblewrap
https://www.packtpub.com/en-us/product/mastering-linux-security-and-hardening-9781837630516
https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
https://stackoverflow.com/questions/9210525/how-do-i-convert-hex-to-decimal-in-python
https://www.geeksforgeeks.org/python-create-a-list-of-tuples/
https://flatkill.org/
https://flatkill.org/2020/
https://xkcd.com/1200/
https://tesk.page/2021/02/11/response-to-flatkill-org/
https://privsec.dev/posts/linux/desktop-linux-hardening/#flatpak
https://man.archlinux.org/man/flatpak-override.1
https://en.wikipedia.org/wiki/Snap_(software)
https://ubuntu.com/blog/a-guide-to-snap-permissions-and-interfaces
https://snapcraft.io/docs/snap-confinement
https://askubuntu.com/questions/1206951/how-can-snap-permissions-be-viewed-and-modified
https://snapcraft.io/docs/interface-management
https://en.wikipedia.org/wiki/Seccomp
https://github.com/netblue30/firejail
https://en.wikipedia.org/wiki/Berkeley_Packet_Filter
https://firejail.wordpress.com/documentation-2/x11-guide/
https://www.man7.org/linux/man-pages/man7/unix.7.html
https://unix.stackexchange.com/questions/608203/whats-the-difference-between-xpra-and-xephyr
https://anyon3.github.io/firejail.html
https://madaidans-insecurities.github.io/linux.html
https://github.com/containers/bubblewrap
https://github.com/igo95862/bubblejail
https://regginator729.wordpress.com/2017/12/12/using-bubblewrap-as-sandbox/
https://misile00.github.io/notes/Bubblewrap
https://wiki.archlinux.org/title/Bubblewrap/Examples
https://sloonz.github.io/posts/sandboxing-1/
https://git.sr.ht/~seirdy/bwrap-scripts/tree/trunk/item/firefox-sandbox
https://wiki.archlinux.org/title/Firejail
https://odysee.com/@netblue30:9/profiles:0
https://firejail.wordpress.com/documentation-2/building-custom-profiles/
Since multiple applications (X.org clients) are able to connect to the same X.Org server - and there is no isolation on the server, this allows the application to have the capabilities to spy on each other, and by extension, the user. According to an answer on StackExchange "[T]here is isolation with X11 -- but it is between users (as controlled by the OS), not between applications executed on behalf of the same user"[2]. Everything you do could be spied on: entering banking credentials, to the root password for your system, password manager credentials, cryptocurrency wallet information, etc. If you want to read more about this, I would highly recommend the following:
From a privacy and security standpoint, this is a big vulnerability to me. To mitigate this, I could just transition over to using . However, since Wayland is a newer technology, I wanted to give it time to be a bit more stable before officially switching to it. In addition, it is not default on NVIDIA-based Pop!_OS ISOs. I did also get issues when trying to switch from X11 to Wayland on Pop!_OS 22.04 LTS x86_64. This led me to learn about two sandboxing solutions for Linux: firejail and bubblejail. I also wanted to dive deeper into a couple package managers that work with sandboxing to some aspect: Flatpak and Snap. However before diving deeper into these, I wanted to replicate a PoC for this vulnerability.
I wanted to test out the lack of application isolation on X11, so this section is repeating a proof of concept (PoC) I saw on a . In order to exploit this vulnerability, you need the following packages: gedit
, xinput
, x11-apps
, graphicsmagick-imagemagick-compat
,and eog
(or any image viewer). On Debian-based systems, this can be downloaded with sudo apt install gedit xinput x11-apps eog graphicsmagick-imagemagick-compat
.
You might also be able to grab the string on the clipboard as well, per: . This would come in handy for grabbing passwords from a user who uses a password manager.
That's all it takes. For updates, it's as simple as a flatpak update -y
(-y
= Automatically answer yes to all questions (or pick the most prioritized answer)). We will get to why the -y
would not be considered a good practice soon. On the , they claim one of the reasons to use Flatpak is its sandboxing:
Let's dive a bit deeper into what sandboxing looks like for Flatpak applications. Based on the documentation, they are using bubblewrap and cgroups, which sounds correct when compared to what I have read in [10]. Bubblewrap is a "tool for constructing sandbox environments" [11]. "bubblewrap works by creating a new, completely empty, mount namespace where the root is on a tmpfs that is invisible from the host, and will be automatically cleaned up when the last process exits. You can then use commandline options to construct the root filesystem and process environment and command to run in the namespace" [11]. This implementation of sandboxing is much better than firejail (we will touch on this later). cgroups on the other hand, allow processes to run in their own kernel space and memory space allowing for segmentation [12]. This can also be used to limit resources a process can use [12]. Both of these tools come together to create a good environment to sandbox applications. However, the implementation of Flatpak itself, is where the sandboxing starts to fall apart.
Reading led me to have a different view on Flatpak. Personally, I never thought too much about the permissions on Flatpak applications, since I assumed it was in some sort of general Flatpak guidelines. It turns out that each application creator can set the permissions and those are the defaults you end up using. This can lead to an app owner choosing more than they need, such as a calculator asking for network access. Let's look at for example:
This is why application confinement is important to me. I want to make sure applications have the exact access they need for them to work; no more, no less. There are a couple of solutions to harden your Flatpaks: and [19,20]. With flatpak override
, this is done through the command line, while Flatseal is a GUI for this; Both reference the same permissions. See the following image of Flatseal:
The post at does have recommendations for what to run as a "privacy/security" baseline:
I did want to mention something here, something I dealt with, but didn't put two and two together until reading the following on : "If you or a Flatpak frontend (app store) simply executes flatpak update -y
, Flatpaks will be automatically granted any new permissions declared upstream without notifying you" [20]. I did notice this when I update with the -y
argument, as well. I usually run the sudo apt update && sudo apt upgrade -y && flatpak update -y
command to update everything in one run, but I plan to change this strategy going forward.
My recommendation for this would be to audit all Flatpak applications you have. Run the general overrides first. Then slowly give the permissions that the application needs to work. For file-related permissions, I would recommend having a specific directory assigned just for your interaction with Flatpak. This directory would be where you put files that you want Flatpak applications to be able to access. You can then update --filesystem=host
to the location you created. I would also recommend using the ":ro" suffix to make sure the permission is for read-only (unless you need it to output files as well)[21]. Some applications implement the , which allows a file manager to pass files to the Flatpak application (e.g. VLC) without specific filesystem access privileges. Despite this, many of them --filesystem=host"[20].
Ubuntu does have documentation that goes a bit deeper into these security technologies here: . There are two modes of snap confinement for applications: strict and classic [7,24]:
If you do want to control the permissions your app has, you can do this via two methods: Snap Store () or the command line [23]. The Snap Store has toggles for application permissions which make it easy to work with:
One thing to mention here, is that the source code for the Snappy application server is not open source [12]. This can lead Ubuntu in the future to potentially add advertisements in Snap applications for Ubuntu Pro (as they already are in apt updates) or put third party ads (as they did in Ubuntu 12 (read more here: )).
Now that the technical deep-end information has been covered, let's get into how to use it. Firejail can be downloaded using your system package manager (apt, yum, dnf, etc.), through the GitHub page (), or through the SourceForge page (). This would be a simple sudo apt install firejail
on a Debian/Ubuntu-derived OS. Using Firejail is really easy, as it comes built in with pre-built profiles for popular applications (I currently see 1150, with ls /etc/firejail/ | grep ".profile$" | wc -l
). Let's "firejail" our first application: the Firefox browser. The basic command is simple: firejail firefox
. This will look in the /etc/firejail/ directory to see if there is a profile for this, then load that profile into Firejail.
This means that there are two sockets are currently running on the X11 server [30]. The X1 mentioned in the output is a where the jail "connects to the X11 server hosting the GNOME desktop itself...it is the 'outer' (aka 'host') X11 server in this case" [1]. The "@" in front of the second socket means that it is an abstract socket, "which is independent of the filesystem" [31]. According to the Firejail docs, "The only way to disable the abstract socket @/tmp/.X11-unix/X0 is by using a network namespace. If for any reasons you cannot use a network namespace, the abstract socket will still be visible inside the sandbox. Hackers can attach keylogger and screenshot programs to this socket." This is essentially saying that we are still vulnerable to the X11 GUI vulnerability. Let's mitigate this by using arguments on Firejail to harden this a bit. I will reference here mostly. It is a great resource, so I would recommend checking it out if you want an in-depth look into Firejail. First let's look at the "--x11=" argument. There are 4 options for this argument: Xorg, Xephyr, Xpra, and Xvfb. Xephyr and Xpra are the main arguments mentioned in the Firejail documentation, so I will focus on those. I was able to find a good explanation comparing the two online [32]:
This is the X11 Xephyr server socket. However, just this change is not enough for GUI isolation. To fix this issue, we need to isolate the host X11 sockets by having them to have their own network namespace. "Network namespaces: these enable containers to have their own network devices, IP addresses, ARP and routing tables, netfilter rules etc.: essentially an isolated network stack" [1]. To do this, we just add an extra argument: "--net=". These networks can be found by running ip addr | grep -oP '\d:\s(\w+)' | awk '{print $2}'
, if your distribution supports the ip addr
command. For my case, I only have two outputs: lo and enp1s0. Since lo is localhost, this won't be able to help us a lot for this, as this is not the network interface the data is going out from. This will not work for a Wi-Fi interface [1]. If you did want to get this running for a Wi-Fi interface, I would recommend checking out this section:
There was an issue created for this on GitHub already (), so I used the solution here to get it working. I tried updating just the Firefox Firejail profile by disabling the "netfilter" setting, but that did not change anything. After I changed "restricted-network yes" to "restricted-network no" in /etc/firejail/firejail.config
, I was able to get Firefox working.
I would of course tweak things to this for myself, such as add --dns=address=9.9.9.9
(Quad9) and --x11=xephyr
or some of the other options here: https://firejail.wordpress.com/documentation-2/firefox-guide/. I'll definitely have to dedicate a session to figuring this out for each app I use Firejail with. If you like the configurations that come default with Firejail, you can run sudo firecfg
and it will take the applications you have in /usr/local/bin/ and create a symbolic link to the profiles. This means you can run firefox
on the command line and firefox will start up as if you typed firejail firefox
. If you end up disliking it, you can just run sudo firecfg --clean
, and it will remove the symbolic links. You can also convert a command and build a profile for yourself if you choose to as well. You can check out the documentation regarding this here: . You can also use firetools (), which is a Firejail GUI, to make creating profiles easier.
Firejail does do a good job in sandboxing a applications, but Firejail itself is not recommended by privacy professionals to use due to what it is: a large SUID binary. This allows Firejail to run with the privileges of the owner of the Firejail executable: root [34]. This means any vulnerability in Firejail can lead to privilege escalation on the system [34]. If you look at the CVEs for Firejail, there are 18 (as of writing this post): , with multiple of them being privilege escalation vulnerabilities [34].
After trying to get Bubblejail (a wrapper for Bubblewrap) to work (see: ), I went to Bubblewrap directly to see how to set it up. Bubblewrap is a "tool for constructing sandbox environments" [11]. "bubblewrap works by creating a new, completely empty, mount namespace where the root is on a tmpfs that is invisible from the host, and will be automatically cleaned up when the last process exits. You can then use commandline options to construct the root filesystem and process environment and command to run in the namespace" [11].
On first glance, one thing I noticed in the Bubblewrap man page is that it did not have a way to add a DNS setting to the sandbox, as Firejail has --dns=address
. My assumption is that this would man that the DNS it uses is the DNS the system uses. For now, let's discuss building up a Bubblewrap "profile" by using parameters. There are a lot of parameters, and those can be seen by doing a bwrap --help
. I see 55 parameters (excluding "--help"). In addition, similar to , I will be slowly adding up and building up parameters for Bubblewrap until it feels sufficient for me.
You can go really in-depth with this and get to seirdy's level: . madaidan summarizes the situation well: "Unfortunately, bubblewrap isn't very widespread and can be difficult to learn. Bubblewrap is essentially a bare bones wrappers around namespaces and seccomp. A user would need decent knowledge on how the filesystem, syscalls and so on work to properly use it" [34]. In addition, on Bubblewraps README.md, it says "bubblewrap is a tool for constructing sandbox environments. bubblewrap is not a complete, ready-made sandbox with a specific security policy" [35].
From a security perspective, Bubblewrap seems to be the obvious choice due to the smaller attack surface (SUID configuration). However, due to its higher learning curve, it puts some people off who would like to leverage sandboxing applications. I did come across during my research, where X11 gets brought up. With Firejail, I had the in-built option to use Xephyr to prevent the user's socket to be accessible by the sandbox. This is not a built in feature in Bubblewrap, but can be integrated externally (yet another thing you will have to configure yourself). There is a good summary at the bottom of as well, comparing these solutions.