Validador Compose
Encontre riscos em contêineres- !privileged: true concede acesso quase no nível do host.
- !Uma senha aparece inline. Use secrets ou um cofre externo de segredos.
- △Fixe a imagem em uma versão imutável ou digest em vez de :latest.
- △A porta publicada parece exposta em todas as interfaces; vincule a 127.0.0.1 quando possível.
- △Considere read_only: true quando o sistema de arquivos raiz não precisa ser gravável.
Introdução
O Validador Compose examina um compose.yaml colado em busca de cinco riscos de segurança de contêineres que aparecem em incidentes de produção: modo privileged, segredos em texto puro, imagens não fixadas, portas vinculadas a todas as interfaces e sistema de arquivos raiz gravável.
Arquivos Compose parecem configuração, mas se tornam a fronteira de segurança dos seus contêineres. Pequenos erros aqui mapeiam diretamente para risco no nível do host.
Objetivo
- Sinalizar privileged: true, que é quase acesso no nível do host.
- Detectar senhas e credenciais escritas inline no arquivo.
- Avisar sobre tags de imagem :latest, que não são reproduzíveis.
- Avisar sobre portas publicadas expostas em todas as interfaces e sobre a ausência de read_only: true.
Entradas
- Um colar de compose.yaml (ou da seção services).
- A estrutura YAML não é profundamente analisada; as verificações são baseadas em padrões no texto visível.
Como funciona
O arquivo é varrido com cinco verificações por padrão. privileged: true é um achado alto porque concede quase todas as capabilities e desativa a maior parte do isolamento.
Qualquer linha com atribuição de senha (password: ou PASSWORD=) é um achado alto: segredos pertencem aos Docker secrets ou a um cofre externo.
image: ...:latest gera um aviso porque o mesmo arquivo pode puxar conteúdos diferentes ao longo do tempo; um digest imutável ou versão fixada é reproduzível.
Uma porta publicada (host:container) não vinculada a 127.0.0.1 é um aviso, assim como um serviço sem read_only: true no sistema de arquivos raiz.
Exemplo testável
Experimente — a análise roda localmente no seu navegador.
Exemplo
services:
api:
image: example/api:latest
ports:
- "8080:8080"
environment:
- DB_PASSWORD=change-me
privileged: trueSaída esperada
Alto: privileged: true concede acesso quase no nível do host. Alto: Uma senha aparece inline. Use secrets ou um cofre externo de segredos. Aviso: Fixe a imagem em uma versão imutável ou digest em vez de :latest. Aviso: A porta publicada parece exposta em todas as interfaces. Aviso: Considere read_only: true quando o sistema de arquivos raiz não precisa ser gravável.
Interpretando a saída
- Remova o modo privileged sempre que possível; a maioria das cargas precisa apenas de capabilities específicas.
- Mova segredos inline para Docker secrets ou um cofre externo e rotacione tudo o que foi commitado.
- Tags fixadas ou digests tornam os deploys reproduzíveis e os rollbacks previsíveis.
- Vincular portas a 127.0.0.1 mantém os serviços privados, a menos que um proxy os exponha deliberadamente.
Riscos
- privileged: true em um contêiner comprometido é, na prática, comprometimento do host.
- Senhas inline vazam para imagens, registries e logs e nunca são rotacionadas de forma limpa.
- :latest quebra rollbacks: a imagem que funcionava ontem pode ser sobrescrita pela build quebrada de hoje.
Limitações
- Verificações por padrão podem perder riscos expressos com anchors YAML, arquivos de ambiente ou instruções do Dockerfile.
- Ela não executa o parser do Compose, então erros de sintaxe YAML não são reportados aqui.
- Não consegue detectar vulnerabilidades nas próprias imagens.
Referências oficiais
FAQ
Quando privileged: true é justificado?
Quase nunca em produção. Alguns drivers legados e acessos a dispositivos específicos exigem; o caminho seguro é conceder exatamente as capabilities necessárias e usar devices: para acesso a hardware.
O que usar em vez de senhas inline?
Docker secrets para swarm, arquivos de ambiente com permissões restritas e referências externas para segredos em cofre. O ponto é que segredos nunca fiquem no arquivo Compose nem na imagem.
read_only: true quebra apps que gravam arquivos?
Só se gravarem no sistema de arquivos raiz. Caminhos graváveis (uploads, caches) podem ser montados como volumes ou declarados com tmpfs, mantendo o resto somente leitura.