
foxcage — Updated!
Firefox in einem rootless Podman-Container mit entfernten Capabilities, isoliertem Netzwerk und ephemerem Speicher ausführen, um Sandbox-Escapes einzudämmen und eine Kompromittierung des Hosts zu verhindern.
foxcage
Führen Sie Firefox in einem rootless Podman-Container für Sicherheitsisolierung aus. Ihr Browser läuft mit fast keinen Linux-Capabilities, in einer eigenen Benutzer- und Netzwerk-Namespace, isoliert vom Host – während er dennoch volle GPU-Beschleunigung, Audio und DRM-Unterstützung bietet.
Warum foxcage?
Firefox hat bereits eine Multi-Prozess-Sandbox, die Web-Content-Renderer mithilfe von Linux-Namespaces und seccomp-bpf isoliert. Für die meisten Bedrohungen ist das effektiv. foxcage fügt eine zweite Mauer hinzu: Wenn ein Angreifer eine Schwachstelle ausnutzt, die Firefox' Sandbox umgeht (was vorkommt – dafür gibt es CVEs), landet er in einem abgeschotteten Container statt in Ihrer vollständigen Benutzersitzung.
Wovor foxcage schützt
- Dateizugriff nach Exploit. Eine Sandbox-Escape bei nacktem Firefox gewährt Zugriff auf alles, was Ihr Benutzer lesen kann:
~/.ssh,~/.gnupg, Browser-Profile anderer Browser, Passwortmanager-Datenbanken, Dokumente, Quellcode. Bei foxcage sieht der Angreifer nur das, was Sie explizit eingebunden haben. - Tracking-Rückstände auf der Festplatte. Der ephemere
@tmp-Käfig hinterlässt nach dem Schließen des Fensters null Spuren auf der Festplatte – einschließlich Erweiterungen, HSTS-Status, TLS-Sitzungscache und DNS-Cache, die Firefox' Privates Fenster weiterhin speichert. Mehrere@tmp-Käfige laufen gleichzeitig, ohne sich gegenseitig zu stören. - Persistenz. Bei nacktem Firefox kann Malware in
~/.config/autostart,~/.bashrc, cron oder anderswo schreiben, um einen Neustart zu überleben. Der ephemere Container von foxcage (--rm) bedeutet, dass nichts bestehen bleibt, es sei denn, Sie haben es per Bind-Mount eingebunden. - Lateraler Netzwerkzugriff. Standardmäßig kann der Container keine Dienste auf
localhostabfragen. Bei nacktem Firefox hat eine Sandbox-Escape vollen Netzwerkzugriff. (Verwenden Sie[network] mode = "host", wenn ein Käfig localhost-Zugriff benötigt, z. B. für lokale Entwicklung – aber beachten Sie den Hinweis unter „Netzwerk": Der Host-Modus legt auch die abstrakten Unix-Sockets des Hosts offen.) - Privilege Escalation. Der Container verwirft alle Linux-Capabilities außer
CAP_SYS_CHROOTund blockiert den Erwerb neuer Privilegien. Setuid-Binaries, Kernel-Exploits über obskure Syscalls und ähnliche Eskalationspfade sind abgeschnitten.
Wovor foxcage nicht schützt
- Angriffe auf Browser-Ebene. Phishing, bösartige Erweiterungen und alles, was innerhalb der normalen Firefox-Funktionalität operiert, bleibt unberührt – foxcage isoliert den Container vom Host, nicht den Benutzer vom Browser.
- Bind-gemountete Verzeichnisse. Alles, was Sie einbinden (
profile,downloads_dir, zusätzliche Bind-Mounts), ist für einen kompromittierten Browser vollständig zugänglich. Wenn Sie ein Host-Profilverzeichnis mounten, kann ein Angreifer es genauso manipulieren wie bei nacktem Firefox. - Audio-Aufnahme über PulseAudio. Der PulseAudio-Socket ist per Bind-Mount in den Container eingebunden. Obwohl er auf Dateisystemebene schreibgeschützt gemountet ist, sind Unix-Domain-Sockets bidirektional – ein kompromittierter Prozess kann dennoch Aufnahmeanfragen über den Socket senden. Eine Browser-Sandbox-Escape könnte potenziell Audio vom Host-Mikrofon aufnehmen.
- Wayland-Compositor-Exploits. Der Wayland-Socket wird durchgereicht. Wayland-Compositor isolieren Clients standardmäßig voneinander, aber eine Schwachstelle im Compositor selbst wäre erreichbar.
Sicherheitskonfiguration
Der Container läuft mit:
- Allen Linux-Capabilities entfernt (nur
CAP_SYS_CHROOTfür Firefox' Content-Sandbox wieder hinzugefügt;CAP_SETUID/CAP_SETGIDvorübergehend hinzugefügt, wenninit.rootkonfiguriert ist) no-new-privileges, um Privilege Escalation zu verhindern- Rootless-Benutzer-Namespace (
--userns keep-id) - Privatem
/dev/shm(nicht mit dem Host geteilt) – konfigurierbare Größe übershm_size - Isoliertem Netzwerk über pasta mit standardmäßig blockiertem Host-Loopback
- DNS verwendet standardmäßig den Host-DNS (konfigurierbar über
network.dns) - Nur bestimmte Sockets aus
XDG_RUNTIME_DIRwerden per Bind-Mount eingebunden (Wayland, PulseAudio, PipeWire und der gefilterte D-Bus-Proxy) – das vollständige Host-Runtime-Verzeichnis wird nie offengelegt - Der Zugriff auf den D-Bus-Session-Bus des Hosts wird immer durch einen gefilterten
xdg-dbus-proxyvermittelt, der auf dem Host läuft. Nurorg.freedesktop.Notifications,org.freedesktop.portal.Desktop,org.mozilla.*und (für Forks) der eigene Namespace des Forks (z. B.org.librewolf.*) sind erreichbar – Session-Dienste wie der Keyring und der SSH/GPG-Agent sind blockiert - Portal-Zugriff ist breit.
org.freedesktop.portal.Desktopist als Ganzes erlaubt, weil darüber der Dateiauswahldialog, „Link in anderer App öffnen" und Bildschirmfreigabe funktionieren. Es legt auchRemoteDesktop(synthetische Tastatur/Maus für die gesamte Sitzung),CameraundLocationoffen. Diese werden durch die eigenen Genehmigungsdialoge Ihres Desktops gesteuert, nicht durch foxcage – und dieRemoteDesktop-Aufforderung ähnelt der Bildschirmfreigabe-Aufforderung, also lesen Sie Genehmigungsdialoge, bevor Sie sie akzeptieren.xdg-dbus-proxyhat keine „eine Schnittstelle verweigern"-Regel, sodass eine Eingrenzung bedeutet, jede Schnittstelle aufzulisten, die Firefox benötigt; siehedocs/DESIGN.mdfür die Gründe, warum das nicht standardmäßig geschieht - Alle Bind-Mounts (
profile,downloads_dir, zusätzliche[mounts] bind) verwendennosuid,noexec - Browser-Download gegen GPG-Signaturen verifiziert: Firefox gegen Mozillas signierte SHA-512-Checksummen, LibreWolf gegen die separate Signatur der LibreWolf-Maintainer plus zugehörige SHA-256. Die Verifizierung ist strenger als
gpg --verify, das bei einer Signatur durch einen widerrufenen Schlüssel und für jeden Schlüssel im Keyring mit Exit-Code 0 endet. foxcage verlangt zusätzlich, dass die Signatur zum festgepinnten Primärschlüssel führt, und lehnt jede Veröffentlichung ab, die von einem Subkey signiert wurde, dessen Besitzer ihn als kompromittiert widerrufen hat – siehe Widerrufene Signaturschlüssel - Ephemerer Container (
--rm) – Dateisystem-Schreibvorgänge gehen beim Beenden verloren - Keine Host-Geräte (Webcam, Sicherheitsschlüssel, Drucker) durchgereicht, sofern nicht explizit aktiviert
Jede [network]- und [mounts]-Option, die Sie aktivieren, tauscht etwas Isolierung gegen Bequemlichkeit. Die Standardwerte sind die restriktivste Konfiguration, die Ihnen dennoch einen nutzbaren Browser bietet.
Anforderungen
- Python 3.11+
- Podman (rootless)
- Wayland-Compositor (X11 wird nicht unterstützt)
- pasta (
sudo apt install passt) – außernetwork.mode = "host" - xdg-dbus-proxy (
sudo apt install xdg-dbus-proxy) - PulseAudio oder PipeWire mit PulseAudio-Kompatibilität (für Audio)
- GPU mit DRI-Unterstützung – optional; ohne
/dev/driwarnt foxcage und Firefox rendert in Software. VA-API-Treiber für Intel, AMD und nouveau sind im Image installiert, sodass Hardware-Videodekodierung ohne Host-Treiberpakete funktioniert – siehe Hardware-Videodekodierung
Führen Sie foxcage als Ihren normalen Desktop-Benutzer aus, nicht als root oder über sudo – die Sandbox mappt Ihren Benutzer in den Container, und das Ausführen als root entfernt die Isolierung, für die foxcage existiert. Es weigert sich, als root zu starten.
Getestete Umgebung: Debian 13 (Trixie) mit GNOME 3. Andere Linux-Distributionen und Wayland-Compositor funktionieren möglicherweise, wurden aber nicht getestet.