Firejail vs Bubblewrap: Which Linux Sandbox Should You Use?

Firejail and Bubblewrap are the two leading lightweight sandboxing tools for Linux, and they take very different approaches to the same problem. Firejail is a feature-rich, SUID-root sandbox shipping over 1,000 pre-built application profiles that work out of the box for browsers, messaging apps, media players, and more. Bubblewrap (bwrap) is a minimal, unprivileged namespace tool - the same one Flatpak uses internally - that gives you precise control over exactly what a sandboxed process can see, at the cost of requiring you to build the sandbox yourself. If you want quick desktop app isolation with sensible defaults, pick Firejail. If you need a minimal, auditable sandbox with no SUID binary and complete control over every mount point and capability, pick Bubblewrap.
Why Sandbox Desktop Applications at All?
Every process running under your Linux user account inherits your full permissions. That means any application - a browser, a chat client, a random Electron app - can read ~/.ssh/, ~/.gnupg/, your browser cookies, your password manager database, and every document in your home directory. There is no permission boundary between programs running as the same user.
This is not a theoretical concern. Supply chain attacks through npm and PyPI packages have become routine. Browser zero-days still appear regularly. Electron apps like Discord, Zoom, and Slack access clipboard contents and filesystem paths well beyond what their stated purpose requires. A single compromised application or malicious browser extension gets access to everything your user account can touch.
Sandboxing restricts what an application can see and do:
- Filesystem visibility: hide sensitive directories like
~/.ssh,~/.gnupg, and~/.configfrom applications that have no business reading them - Network access: block network entirely or restrict it to specific protocols
- IPC isolation: prevent X11 keylogging, a real risk under Xorg where any application can capture keystrokes from any other
- Device access: block webcam and microphone unless explicitly granted
- System call filtering: seccomp-bpf filters restrict which kernel interfaces the process can use
The same seccomp-bpf and capability-dropping techniques apply to hardening container images โ the defense-in-depth principles translate directly between namespace-based sandboxes and Docker containers.
Flatpak and Snap already provide sandboxing, but not every application ships as a Flatpak, and many Flatpak packages request --filesystem=home, which defeats much of the purpose. Firejail and Bubblewrap let you sandbox any native package installed through your distribution’s package manager.
Wayland’s protocol provides per-surface isolation by default - no application can capture another’s input or output. But Xwayland, which many legacy apps still require, breaks this isolation. Sandboxing fills the gap for those applications.
Sandboxing is not a substitute for keeping software updated. It is a defense-in-depth layer that limits the damage when prevention fails.
Firejail - Feature-Rich Sandboxing with Pre-Built Profiles
Firejail is the more approachable of the two tools. Install it, type firejail firefox, and your browser launches inside a sandbox with a curated set of restrictions drawn from Firefox’s built-in security profile. The current stable version is 0.9.80, with the 0.9.74 release (March 2025) having introduced experimental Landlock LSM
support for kernel-level filesystem access control.
Installation
On Debian 13+ or Ubuntu 24.04+:
sudo apt install firejail firejail-profilesOn Fedora 41+:
sudo dnf install firejailVerify with firejail --version. You should see 0.9.74 or later.
How It Works
Firejail is a SUID-root binary. When you run firejail firefox, it:
- Creates Linux namespaces (mount, PID, network, UTS) to isolate the process
- Applies seccomp-bpf syscall filters to restrict available kernel interfaces
- Mounts a restricted filesystem view based on the application’s profile
- Drops all elevated privileges
- Executes the target application inside the sandbox
The SUID-root design means Firejail works on any Linux system regardless of whether unprivileged user namespaces are enabled. This is both its strength and its primary criticism (more on that in the comparison section).

Basic Usage
Launch Firefox with its default sandbox profile:
firejail firefoxLaunch Discord with a temporary, empty home directory that gets discarded on exit:
firejail --private discordSee what restrictions a profile applies:
firejail --debug firefoxKey Profile Directives
Firejail profiles use a declarative syntax to define restrictions:
| Directive | Effect |
|---|---|
whitelist ~/Downloads | Only expose the Downloads directory |
blacklist ~/.ssh | Hide SSH keys from the sandboxed app |
net none | Disable all network access |
protocol unix,inet,inet6 | Restrict allowed socket types |
seccomp | Enable default syscall filter |
caps.drop all | Drop all Linux capabilities |
noroot | Prevent SUID binaries inside the sandbox |
--landlock | Enable Landlock filesystem restrictions (0.9.74+) |
Customizing Profiles
To modify a profile, copy it to your user config directory:
cp /etc/firejail/firefox.profile ~/.config/firejail/firefox.profileEdit the copy to add or remove restrictions. Your user-level profile takes precedence over the system one.
Desktop Integration
Running sudo firecfg rewrites symlinks in /usr/local/bin/ so that every profiled application launched from your desktop menu, dmenu, or rofi automatically runs through Firejail. This is the easiest way to sandbox your entire desktop without changing habits.

Recent Notable Changes
The 0.9.78 release (January 2026) was an emergency fix for a GTK compatibility issue: applications using glycin
2.0.0 or later via gdk-pixbuf2 (Firefox, Thunderbird, GIMP) were crashing inside Firejail sandboxes. The fix replaced bubblewrap calls within the sandbox with a dummy fbwrap program. A --allow-bwrap flag was added for cases where the real bwrap is needed.
Bubblewrap - Minimal Unprivileged Namespace Sandboxing
Bubblewrap takes the opposite approach from Firejail. It is a minimal, low-level tool for constructing Linux namespaces without requiring SUID-root. You build the sandbox mount by mount, specifying exactly which directories the process can see and whether they are read-only or writable. This gives maximum control and auditability at the cost of significantly more effort per application.
The current stable version is 0.11.1.
Installation
On Debian 13+ or Ubuntu 24.04+:
sudo apt install bubblewrapOn Fedora 41+:
sudo dnf install bubblewrapVerify with bwrap --version.
How It Works
Bubblewrap uses clone() with CLONE_NEWUSER, CLONE_NEWNS, CLONE_NEWPID, and related flags to create unprivileged user namespaces
. On most modern distributions (Ubuntu 24.04+, Fedora 40+, Arch), kernel.unprivileged_userns_clone is enabled by default, so bwrap runs without any SUID binary. This smaller trusted computing base is one of its primary advantages.
Basic Sandbox Example
Launch Firefox with a minimal root filesystem and an empty home directory:
bwrap \
--ro-bind /usr /usr \
--ro-bind /lib /lib \
--ro-bind /lib64 /lib64 \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--proc /proc \
--dev /dev \
--tmpfs /tmp \
--tmpfs /home \
--unshare-all \
--share-net \
--new-session \
-- /usr/bin/firefoxThis creates a read-only view of the system libraries, an empty home directory, and shares the host network (since Firefox needs it). Everything else is hidden.
Mount Types
| Flag | Effect |
|---|---|
--bind src dest | Read-write bind mount |
--ro-bind src dest | Read-only bind mount |
--tmpfs path | Ephemeral tmpfs (contents lost on exit) |
--dev-bind src dest | Device access (for GPU, etc.) |
--symlink src dest | Create a symlink for FHS compatibility |
--unshare-net | Loopback-only network namespace |
--share-net | Keep host networking |
--die-with-parent | Kill sandboxed process when parent exits |
Network Isolation
Adding --unshare-net gives the process a loopback-only network namespace with no external connectivity. Use --share-net to keep host networking. Unlike Firejail, there is no built-in support for network bridges, bandwidth limits, or DNS filtering - it is strictly all-or-nothing.
Wrapper Scripts
Since bwrap commands are verbose, the standard approach is to write shell wrapper scripts. For example, ~/bin/sandboxed-firefox.sh:
#!/bin/bash
exec bwrap \
--ro-bind /usr /usr \
--ro-bind /lib /lib \
--ro-bind /lib64 /lib64 \
--ro-bind /etc/fonts /etc/fonts \
--ro-bind /etc/resolv.conf /etc/resolv.conf \
--bind ~/.mozilla ~/.mozilla \
--bind ~/Downloads ~/Downloads \
--proc /proc \
--dev /dev \
--tmpfs /tmp \
--unshare-all \
--share-net \
--new-session \
-- /usr/bin/firefox "$@"Bubblejail - A Higher-Level Frontend
If writing raw bwrap commands feels tedious, Bubblejail
provides a Firejail-like experience on top of Bubblewrap. It offers a GUI for managing sandboxed instances, with each instance getting its own separate home directory. Profiles are configured through a services.toml file that defines which system resources (PulseAudio, GPU, network) the sandbox can access.

Create a sandboxed Firefox instance:
bubblejail create --profile firefox FirefoxInstanceBubblejail ships about 50 pre-built profiles compared to Firejail’s 1,000+, but it covers the most common desktop applications.
Head-to-Head Comparison
Choosing between these tools depends on your threat model, technical comfort, and how much time you want to invest in configuration.
| Dimension | Firejail | Bubblewrap |
|---|---|---|
| Setup effort | firejail app-name works immediately | Manual mount construction required |
| Profile ecosystem | 1,000+ upstream profiles | None built-in (Bubblejail has ~50) |
| SUID requirement | Yes (SUID-root binary) | No (unprivileged namespaces) |
| Attack surface | Larger (SUID binary has had CVEs) | Smaller (no privileged binary) |
| Network sandboxing | Per-app bridges, bandwidth limits, DNS filtering | All-or-nothing namespace isolation |
| D-Bus filtering | Built-in proxy support | Requires external xdg-dbus-proxy |
| Landlock support | Experimental (0.9.74+) | Not applicable (use with other tools) |
| Performance overhead | Negligible (~5ms namespace setup) | Negligible (~5ms namespace setup) |
| Desktop integration | firecfg auto-sandboxes all profiled apps | Manual (wrapper scripts or Bubblejail) |
The SUID Question
Firejail’s SUID-root binary has been the source of real security incidents. CVE-2022-31214 was a privilege escalation vulnerability in Firejail’s join.c that allowed local attackers to craft a bogus Firejail container, trick the SUID-root binary into joining it, and escape to full root access. The vulnerability affected versions before 0.9.68 and was patched, but it illustrates the fundamental tension: a security tool with root privileges becomes an attractive attack target itself.
Bubblewrap avoids this entirely by operating within unprivileged user namespaces. There is no privileged binary to exploit. The trade-off is that bwrap requires the kernel to have unprivileged user namespaces enabled, which is the default on most distributions since 2024 but can be disabled by administrators.
When to Pick Which
Choose Firejail when:
- You want to sandbox many desktop applications with minimal effort
- You need network filtering, DNS overrides, or bandwidth controls per application
- You are on a system without unprivileged user namespaces
- You want the
firecfgauto-sandbox feature for your entire desktop
Choose Bubblewrap when:
- SUID-root binaries are unacceptable in your threat model
- You need to audit every aspect of the sandbox configuration
- You are sandboxing a small number of specific applications and can invest time per app
- You already use Flatpak and want to understand or customize its underlying sandbox
Practical Sandboxing Recipes
Firefox with Firejail
Allow only Downloads and the Firefox profile directory:
firejail --whitelist=~/Downloads --whitelist=~/.mozilla firefoxAdd DNS override for privacy:
firejail --whitelist=~/Downloads --whitelist=~/.mozilla --dns=9.9.9.9 firefoxDiscord with an Isolated Home
Give Discord its own persistent home directory, separate from your real one:
firejail --private=~/.sandboxes/discord discordAnalyzing an Untrusted Binary
Run a suspicious binary with no network, no home directory, and automatic cleanup:
bwrap \
--ro-bind /usr /usr \
--ro-bind /lib /lib \
--ro-bind /lib64 /lib64 \
--proc /proc \
--dev /dev \
--tmpfs /tmp \
--tmpfs /home \
--unshare-all \
--new-session \
--die-with-parent \
-- ./suspicious-binaryThe --die-with-parent flag ensures the sandboxed process is killed if your terminal session exits. The same pattern underpins local AI code interpreter agents
that need to execute untrusted LLM-generated code in an ephemeral sandbox.
VS Code with Restricted Filesystem
Restrict VS Code to only see your Projects and Downloads directories:
firejail --whitelist=~/Projects --whitelist=~/Downloads --seccomp codeNote that VS Code’s integrated terminal inherits these sandbox restrictions, so shell commands inside VS Code are also confined.
Browser Profile Isolation
Run separate browser instances for different activities, each with its own isolated storage:
# Banking browser - no access to other profiles
firejail --private=~/.sandboxes/browser-banking firefox --no-remote
# Social media browser
firejail --private=~/.sandboxes/browser-social firefox --no-remote
# General browsing
firejail --private=~/.sandboxes/browser-general firefox --no-remoteEach instance gets its own cookies, history, and extensions with no cross-access.
Steam with Restricted Access
Prevent Steam from reading your documents, SSH keys, or browser data:
firejail --whitelist=~/.local/share/Steam --whitelist=~/Games steamFull GPU and network access is preserved since games need both.
Beyond Firejail and Bubblewrap
A few related technologies overlap with or complement these tools:
Landlock
is a kernel-level LSM that allows unprivileged processes to restrict their own filesystem access. Landrun
is a standalone tool built on Landlock that provides Firejail-like usability without SUID. Firejail 0.9.74+ can use Landlock as an additional restriction layer via the --landlock flag.
For system services rather than desktop apps, systemd offers its own sandboxing directives: DynamicUser=, ProtectHome=, PrivateNetwork=, and similar options that provide isolation without any extra tools.
AppArmor and SELinux are Mandatory Access Control frameworks that enforce restrictions at the kernel level, independent of namespaces. Both can be layered on top of Firejail or Bubblewrap.
The xdg-desktop-portal system provides controlled access to host resources (file picker, screen sharing, printing) through D-Bus interfaces, allowing sandboxed apps to request specific permissions on demand rather than getting blanket filesystem access.
For most desktop Linux users, Firejail’s profile library and ease of use make it the practical starting point. If the SUID-root model concerns you, Bubblejail offers a middle ground between Firejail’s convenience and Bubblewrap’s minimal trusted computing base. And for the security-conscious willing to invest time per application, raw Bubblewrap commands give you the tightest possible sandbox with full auditability.
Botmonster Tech