Voltar às atualizações
UpdatedAug 6, 2026

foxcage — Updated!

Execute o Firefox em um contêiner Podman rootless, com capabilities removidas, rede isolada e armazenamento efêmero para conter escapes de sandbox e evitar o comprometimento do host.

Compartilhar

ícone foxcage foxcage

Execute o Firefox em um contêiner Podman sem root para isolamento de segurança. Seu navegador roda com quase nenhuma capability do Linux, em seu próprio namespace de usuário e de rede, isolado do host — enquanto ainda tem aceleração de GPU completa, áudio e suporte a DRM.

Por que foxcage?

O Firefox já possui um sandbox multiprocesso que isola os renderizadores de conteúdo web usando namespaces do Linux e seccomp-bpf. Para a maioria das ameaças, isso é eficaz. O foxcage adiciona uma segunda parede: se um atacante explorar uma vulnerabilidade que escape do sandbox do Firefox (o que acontece — existem CVEs para isso), ele cairá dentro de um contêiner bloqueado em vez da sua sessão de usuário completa.

O que o foxcage protege contra

  • Acesso a arquivos pós-exploração. Uma fuga de sandbox no Firefox puro dá acesso a tudo que seu usuário pode ler: ~/.ssh, ~/.gnupg, perfis de navegador de outros navegadores, bancos de dados de gerenciadores de senhas, documentos, código-fonte. No foxcage, o atacante vê apenas o que você montou explicitamente.
  • Resíduos de rastreamento em disco. A gaiola efêmera @tmp deixa zero vestígios no disco após o fechamento da janela — incluindo extensões, estado HSTS, cache de sessão TLS e cache DNS que a Navegação Privada do Firefox ainda persiste. Várias gaiolas @tmp rodam simultaneamente sem interferir umas nas outras.
  • Persistência. No Firefox puro, malware pode gravar em ~/.config/autostart, ~/.bashrc, cron ou em qualquer outro lugar para sobreviver a uma reinicialização. O contêiner efêmero do foxcage (--rm) significa que nada persiste a menos que você o tenha montado via bind.
  • Movimento lateral na rede. Por padrão, o contêiner não pode sondar serviços em localhost. No Firefox puro, uma fuga de sandbox tem acesso total à rede. (Use [network] mode = "host" se uma gaiola precisar de acesso a localhost, por exemplo, para desenvolvimento local — mas veja a ressalva em "Rede": o modo host também expõe os sockets Unix abstratos do host.)
  • Escalonamento de privilégios. O contêiner remove todas as capabilities do Linux, exceto CAP_SYS_CHROOT, e bloqueia a aquisição de novos privilégios. Binários setuid, exploits de kernel via syscalls obscuras e caminhos de escalonamento semelhantes são cortados.

O que o foxcage não protege contra

  • Ataques no nível do navegador. Phishing, extensões maliciosas e qualquer coisa que opere dentro da funcionalidade normal do Firefox não é afetada — o foxcage isola o contêiner do host, não o usuário do navegador.
  • Diretórios montados via bind. Qualquer coisa que você monte (profile, downloads_dir, montagens bind extras) é totalmente acessível a um navegador comprometido. Se você montar um diretório de perfil do host, um atacante pode adulterá-lo assim como no Firefox puro.
  • Captura de áudio via PulseAudio. O socket do PulseAudio é montado via bind no contêiner. Embora seja montado somente leitura no nível do sistema de arquivos, sockets de domínio Unix são bidirecionais — um processo comprometido ainda pode enviar solicitações de gravação através do socket. Uma fuga de sandbox do navegador poderia potencialmente gravar áudio do microfone do host.
  • Exploits do compositor Wayland. O socket Wayland é repassado. Os compositores Wayland isolam clientes uns dos outros por design, mas uma vulnerabilidade no próprio compositor seria alcançável.

Configuração de segurança

O contêiner roda com:

  • Todas as capabilities do Linux removidas (apenas CAP_SYS_CHROOT adicionada de volta para o sandbox de conteúdo do Firefox; CAP_SETUID/CAP_SETGID adicionadas temporariamente quando init.root está configurado)
  • no-new-privileges para impedir escalonamento de privilégios
  • Namespace de usuário sem root (--userns keep-id)
  • /dev/shm privado (não compartilhado com o host) — tamanho configurável via shm_size
  • Rede isolada via pasta com loopback do host bloqueado por padrão
  • DNS usa o DNS do host por padrão (configurável via network.dns)
  • Apenas sockets específicos de XDG_RUNTIME_DIR são montados via bind (Wayland, PulseAudio, PipeWire e o proxy D-Bus filtrado) — o diretório de runtime completo do host nunca é exposto
  • O acesso ao barramento de sessão D-Bus do host é sempre mediado por um xdg-dbus-proxy filtrado rodando no host. Apenas org.freedesktop.Notifications, org.freedesktop.portal.Desktop, org.mozilla.* e (para forks) o namespace próprio do fork (por exemplo, org.librewolf.*) são alcançáveis — serviços de sessão como o keyring e o agente SSH/GPG são bloqueados
  • O acesso a portais é amplo. org.freedesktop.portal.Desktop é permitido como um todo, porque é assim que o seletor de arquivos, "abrir link em outro aplicativo" e o compartilhamento de tela funcionam. Ele também expõe RemoteDesktop (teclado/mouse sintético para toda a sessão), Camera e Location. Esses são controlados pelos diálogos de aprovação do seu próprio desktop, não pelo foxcage — e o prompt de RemoteDesktop se assemelha ao prompt de compartilhamento de tela, então leia os diálogos de aprovação antes de aceitá-los. O xdg-dbus-proxy não tem regra de "negar uma interface", então restringir isso significa enumerar cada interface que o Firefox precisa; veja docs/DESIGN.md para saber por que isso não é feito por padrão
  • Todas as montagens bind (profile, downloads_dir, [mounts] bind extras) usam nosuid,noexec
  • Download do navegador verificado contra assinaturas GPG: Firefox contra as somas SHA-512 assinadas da Mozilla, LibreWolf contra a assinatura destacada dos Mantenedores do LibreWolf mais SHA-256 irmão. A verificação é mais rigorosa que gpg --verify, que sai com 0 para uma assinatura feita por uma chave revogada e para qualquer chave no chaveiro. O foxcage adicionalmente exige que a assinatura encadeie até a chave primária fixada e recusa qualquer lançamento assinado por uma subchave que seu proprietário revogou como comprometida — veja Chaves de assinatura revogadas
  • Contêiner efêmero (--rm) — gravações no sistema de arquivos são perdidas ao sair
  • Sem dispositivos do host (webcam, chaves de segurança, impressoras) repassados, a menos que habilitados explicitamente

Cada opção [network] e [mounts] que você habilitar troca algum isolamento por conveniência. Os padrões são a configuração mais restritiva que ainda oferece um navegador utilizável.

Requisitos

  • Python 3.11+
  • Podman (sem root)
  • Compositor Wayland (X11 não é suportado)
  • pasta (sudo apt install passt) — a menos que network.mode = "host"
  • xdg-dbus-proxy (sudo apt install xdg-dbus-proxy)
  • PulseAudio ou PipeWire com compatibilidade com PulseAudio (para áudio)
  • GPU com suporte a DRI — opcional; sem /dev/dri, o foxcage avisa e o Firefox renderiza em software. Drivers VA-API para Intel, AMD e nouveau são instalados na imagem, então a decodificação de vídeo por hardware funciona sem pacotes de driver do host — veja Decodificação de vídeo por hardware

Execute o foxcage como seu usuário normal de desktop, não como root ou via sudo — o sandbox mapeia seu usuário para dentro do contêiner, e rodar como root remove o isolamento para o qual o foxcage existe. Ele se recusa a iniciar como root.

Ambiente testado: Debian 13 (Trixie) com GNOME 3. Outras distribuições Linux e compositores Wayland podem funcionar, mas não foram testados.

Instalação

O foxcage é um único script Python sem dependências fora da biblioteca padrão do Python. Copie-o para um diretório no seu PATH:```sh sudo cp foxcage /usr/local/bin/foxcage

Ou para uma instalação local do usuário:```sh
cp foxcage ~/.local/bin/foxcage

Certifique-se de que o script é executável (chmod +x foxcage).

Categorias