Volver a actualizaciones
ActualizadaAug 8, 2026

foxcage — Actualizado!

Ejecuta Firefox en un contenedor Podman sin root, con capacidades retiradas, red aislada y almacenamiento efímero para contener fugas del sandbox y evitar el compromiso del host.

Compartir

icono de foxcage foxcage

Ejecuta Firefox en un contenedor Podman sin root para aislamiento de seguridad. Tu navegador se ejecuta con casi ninguna capacidad de Linux, en su propio espacio de usuario y de red, aislado del host — mientras sigue teniendo aceleración GPU completa, audio y soporte DRM.

¿Por qué foxcage?

Firefox ya tiene un sandbox multiproceso que aísla los renderizadores de contenido web usando namespaces de Linux y seccomp-bpf. Para la mayoría de las amenazas, esto es efectivo. foxcage añade una segunda pared: si un atacante explota una vulnerabilidad que escapa del sandbox de Firefox (lo cual ocurre — hay CVEs para esto), aterriza dentro de un contenedor bloqueado en lugar de en tu sesión de usuario completa.

Contra qué protege foxcage

  • Acceso a archivos post-explotación. Una fuga del sandbox en Firefox sin contenedor da acceso a todo lo que tu usuario puede leer: ~/.ssh, ~/.gnupg, perfiles de navegador de otros navegadores, bases de datos de gestores de contraseñas, documentos, código fuente. En foxcage, el atacante solo ve lo que has montado explícitamente.
  • Residuos de rastreo en disco. La jaula efímera @tmp deja cero rastro en disco después de cerrar la ventana — incluyendo extensiones, estado HSTS, caché de sesión TLS y caché DNS que la Navegación Privada de Firefox aún persiste. Múltiples jaulas @tmp se ejecutan de forma concurrente sin interferir entre sí.
  • Persistencia. En Firefox sin contenedor, el malware puede escribir en ~/.config/autostart, ~/.bashrc, cron, o en cualquier otro lugar para sobrevivir a un reinicio. El contenedor efímero de foxcage (--rm) significa que nada persiste a menos que lo hayas montado con bind.
  • Movimiento lateral en la red. Por defecto, el contenedor no puede sondear servicios en localhost. En Firefox sin contenedor, una fuga del sandbox tiene acceso completo a la red. (Usa [network] mode = "host" si una jaula necesita acceso a localhost, p. ej. para desarrollo local — pero consulta la advertencia en "Redes": el modo host también expone los sockets Unix abstractos del host).
  • Escalada de privilegios. El contenedor elimina todas las capacidades de Linux excepto CAP_SYS_CHROOT y bloquea la adquisición de nuevos privilegios. Los binarios setuid, los exploits del kernel mediante syscalls oscuras y rutas de escalada similares quedan cortados.

Contra qué no protege foxcage

  • Ataques a nivel de navegador. El phishing, las extensiones maliciosas y cualquier cosa que opere dentro de la funcionalidad normal de Firefox no se ve afectada — foxcage aísla el contenedor del host, no al usuario del navegador.
  • Directorios montados con bind. Cualquier cosa que montes (profile, downloads_dir, montajes bind adicionales) es totalmente accesible para un navegador comprometido. Si montas un directorio de perfil del host, un atacante puede manipularlo igual que en Firefox sin contenedor.
  • Captura de audio vía PulseAudio. El socket de PulseAudio se monta con bind dentro del contenedor. Aunque está montado de solo lectura a nivel del sistema de archivos, los sockets de dominio Unix son bidireccionales — un proceso comprometido aún puede enviar solicitudes de grabación a través del socket. Una fuga del sandbox del navegador podría potencialmente grabar audio del micrófono del host.
  • Exploits del compositor Wayland. El socket de Wayland se pasa a través. Los compositores Wayland aíslan a los clientes entre sí por diseño, pero una vulnerabilidad en el propio compositor sería alcanzable.

Configuración de seguridad

El contenedor se ejecuta con:

  • Todas las capacidades de Linux eliminadas (solo se añade CAP_SYS_CHROOT para el sandbox de contenido de Firefox; CAP_SETUID/CAP_SETGID se añaden temporalmente cuando init.root está configurado)
  • no-new-privileges para prevenir la escalada de privilegios
  • Namespace de usuario sin root (--userns keep-id)
  • /dev/shm privado (no compartido con el host) — tamaño configurable vía shm_size
  • Red aislada mediante pasta con loopback del host bloqueado por defecto
  • DNS usa el DNS del host por defecto (configurable vía network.dns)
  • Solo sockets específicos de XDG_RUNTIME_DIR se montan con bind (Wayland, PulseAudio, PipeWire y el proxy D-Bus filtrado) — el directorio de runtime completo del host nunca se expone
  • El acceso al bus de sesión D-Bus del host siempre está mediado por un xdg-dbus-proxy filtrado que se ejecuta en el host. Solo org.freedesktop.Notifications, org.freedesktop.portal.Desktop, org.mozilla.* y (para forks) el propio namespace del fork (p. ej. org.librewolf.*) son alcanzables — los servicios de sesión como el llavero y el agente SSH/GPG están bloqueados
  • El acceso a portales es amplio. org.freedesktop.portal.Desktop se permite en su totalidad, porque así es como funcionan el selector de archivos, "abrir enlace en otra aplicación" y el uso compartido de pantalla. También expone RemoteDesktop (teclado/ratón sintético para toda la sesión), Camera y Location. Estos están controlados por los propios diálogos de aprobación de tu escritorio, no por foxcage — y el aviso de RemoteDesktop se parece al aviso de compartir pantalla, así que lee los diálogos de aprobación antes de aceptarlos. xdg-dbus-proxy no tiene una regla de "denegar una interfaz", así que reducir esto significa enumerar cada interfaz que Firefox necesita; consulta docs/DESIGN.md para saber por qué no se hace por defecto
  • Todos los montajes bind (profile, downloads_dir, [mounts] bind adicionales) usan nosuid,noexec
  • La descarga del navegador se verifica contra firmas GPG: Firefox contra las sumas SHA-512 firmadas de Mozilla, LibreWolf contra la firma separada de los Mantenedores de LibreWolf más SHA-256 hermano. La verificación es más estricta que gpg --verify, que sale con 0 para una firma hecha por una clave revocada y para cualquier clave en el llavero. foxcage además requiere que la firma encadene con la clave primaria fijada, y rechaza cualquier lanzamiento firmado por una subclave que su propietario haya revocado como comprometida — consulta Claves de firma revocadas
  • Contenedor efímero (--rm) — las escrituras en el sistema de archivos se pierden al salir
  • Sin dispositivos del host (cámara web, claves de seguridad, impresoras) pasados a través a menos que se habiliten explícitamente

Cada opción de [network] y [mounts] que habilites intercambia algo de aislamiento por conveniencia. Los valores por defecto son la configuración más restrictiva que aún te da un navegador utilizable.

Requisitos

  • Python 3.11+
  • Podman (sin root)
  • Compositor Wayland (X11 no es compatible)
  • pasta (sudo apt install passt) — a menos que network.mode = "host"
  • xdg-dbus-proxy (sudo apt install xdg-dbus-proxy)
  • PulseAudio o PipeWire con compatibilidad con PulseAudio (para audio)
  • GPU con soporte DRI — opcional; sin /dev/dri foxcage advierte y Firefox renderiza en software. Los controladores VA-API para Intel, AMD y nouveau están instalados en la imagen, así que la decodificación de video por hardware funciona sin paquetes de controladores del host — consulta Decodificación de video por hardware (VA-API)

Ejecuta foxcage como tu usuario de escritorio normal, no como root ni vía sudo — el sandbox mapea tu usuario dentro del contenedor, y ejecutarlo como root elimina el aislamiento para el que existe foxcage. Se niega a iniciarse como root.

Entorno probado: Debian 13 (Trixie) con GNOME 3. Otras distribuciones de Linux y compositores Wayland pueden funcionar pero no han sido probados.

Instalación

Categorías