Uma imagem do Docker é composta por uma pilha de camadas, que são conjuntos imutáveis e de leitura apenas de alterações no sistema de ficheiros, sobrepostas às camadas inferiores. Na base encontra-se o sistema operativo de base, seguido dos pacotes necessários para o seu funcionamento e, por fim, o seu próprio código no topo. Proteger as imagens do Docker significa controlar o que é incluído nelas e mantê-las atualizadas após a sua distribuição.
A maioria das vulnerabilidades de uma imagem do tipo « container » provém dos pacotes e bibliotecas de código aberto que a acompanham. Alguns, como o cURL ou um shell, podem nunca vir a ser chamados pela sua aplicação assim que o « container » estiver a funcionar, pelo que podem ser removidos da imagem. Outros, como a glibc, são necessários para o funcionamento da sua aplicação e não podem ser removidos. O restante das vulnerabilidades resulta, normalmente, de erros humanos, como um segredo incorporado numa camada ou um « container » deixado a funcionar com privilégios de root.
Este artigo aborda a origem do risco numa imagem do Docker, explica como manter as imagens protegidas é um problema de « gerenciamento de vulnerabilidades », apresenta as três formas como as ferramentas mantêm uma imagem base atualizada com patches e descreve como o « Aikido » protege e atualiza com patches as imagens que já está a executar.
{{cta}}
TL;DR
A segurança das imagens do Docker envolve a remoção de pacotes não utilizados e a aplicação de correções às vulnerabilidades no que resta. A remoção de pacotes não utilizados apenas elimina as vulnerabilidades dos elementos de que não necessita. Um pacote vulnerável do qual a sua aplicação realmente depende continua a necessitar de uma correção, e mesmo uma imagem minimizada continua a acumular novas vulnerabilidades. Além disso, a adoção de imagens reforçadas envolve frequentemente a migração para outra distribuição e a atualização de acordo com o ritmo de outra entidade. O Aikido fornece novas compilações corrigidas das mesmas versões da imagem base, disponibilizadas através de PR. Se tiver fixado uma versão, isto permite-lhe manter-se nessa versão, sem alterações que causem incompatibilidades nem a necessidade de migrar para uma nova imagem.
De onde provém o risco numa imagem do Docker
O FROM A linha é a primeira instrução num Dockerfile, que indica a imagem base sobre a qual se está a construir. A A PARTIR do nó:24 define a imagem oficial do Node.js 24 como base, a qual inclui o ambiente de execução do Node.js e, subjacente a este, um sistema Debian completo. Isso inclui um shell, um gestor de pacotes e bibliotecas do sistema, cada um dos quais pode conter vulnerabilidades que herda antes mesmo de escrever uma única linha do seu próprio código.
Cada instrução do Dockerfile adiciona uma camada por cima da anterior, e as camadas são imutáveis. Apagar algo numa camada posterior apenas o oculta, pelo que tudo o que vem incluído na base permanece na imagem, quer a sua aplicação o utilize ou não. A sua aplicação nunca recorre à maior parte do que vem incluído na base, mas cada pacote que aí se encontra constitui uma superfície de ataque.
Por exemplo, a CVE-2023-4911 («Looney Tunables») era uma falha de escalada de privilégios locais no carregador dinâmico da glibc, um componente presente na camada base de praticamente todas as imagens Linux mais comuns. A glibc vinha incluída na distribuição e qualquer container compilado a partir de uma base afetada continha essa falha.
Bases diferentes, riscos diferentes
Nem todas as imagens base incluem a mesma quantidade de componentes. Uma imagem de distribuição completa inclui muito mais do que a sua aplicação necessita, incluindo um shell e um gestor de pacotes que provavelmente nunca irá utilizar. Uma variante «slim» reduz parte desses componentes. Uma imagem «distroless» elimina completamente o shell e o gestor de pacotes, mantendo apenas o que o ambiente de execução necessita. O Alpine é pequeno por definição e, uma vez que é construído com base no musl em vez do glibc, nem sequer foi afetado pelos Looney Tunables.
Manter as imagens protegidas é um problema de « gerenciamento de vulnerabilidades »
Uma imagem consolidada está segura no dia em que é criada, mas vai-se desatualizando com o tempo, à medida que são descobertas novas vulnerabilidades nos pacotes que já nela se encontram. Mantê-la segura significa tratar a imagem como algo que deve ser verificado novamente à luz de novas divulgações e ao qual devem ser aplicadas novas correções de forma contínua. A versão manual implica acompanhar as divulgações em todos os pacotes de todas as bases e aplicar manualmente cada correção através de backport ou atualização da versão.
Fixar uma versão de confiança faz sentido quando já testou essa versão e pretende continuar a utilizá-la, mas ainda assim é necessário estar atento a novas divulgações. Uma imagem que seja fixada e depois esquecida irá acumular vulnerabilidades recém-descobertas. Se essa imagem atingir o fim de vida útil e deixar de receber correções do fornecedor original, a sua lista de falhas conhecidas e sem correção irá aumentar. Por exemplo, o Node.js 20 atingiu o fim de vida útil a 30 de abril de 2026; assim, um ` container ` ainda fixado em `node:20` continua a funcionar, mas todas as vulnerabilidades divulgadas relativamente a essa versão desde então ficam sem correção, sem que haja qualquer correção prevista.
O instinto oposto, de avançar sempre para a versão mais recente, é igualmente errado. Por exemplo, a porta de acesso não autorizada «xz-utils» é uma biblioteca de compressão que vem incluída na maioria das imagens base do Linux. Esta estava presente em duas versões recentes específicas, a 5.6.0 e a 5.6.1, e as equipas que ainda utilizavam a linha mais antiga 5.4 nunca ficaram expostas ao risco. A orientação posterior da CISA foi para fazer o downgrade, e não o upgrade.
O que realmente garante a vossa segurança é tomar decisões ponderadas sobre as versões que utilizam. Imaginem uma equipa que fixa a versão «debian:bookworm», regista que a escolheu em detrimento da versão mais recente porque a testou e esta é estável, e verifica se há novas vulnerabilidades à medida que estas são divulgadas. Quando uma nova vulnerabilidade CVE é divulgada num pacote dessa imagem, eles já sabem que o utilizam e porquê. Isso permite-lhes ponderar a exposição real em relação ao custo da mudança.
Como proteger imagens do Docker
Reduzir a superfície de ataque
Comece por uma imagem base mínima ou pré-fortalecida. A imagem base determina a maior parte do que irá herdar, pelo que esta é a escolha com maior impacto que irá fazer. (Este tema será abordado com mais pormenor na próxima secção)
Utilize compilações em várias fases para manter as ferramentas de compilação fora da imagem final. A compilação da imagem normalmente inclui um compilador, cabeçalhos de desenvolvimento e um gestor de pacotes para compilar a sua aplicação e instalar as suas dependências. Numa compilação de fase única, tudo isso fica incorporado na imagem final, mesmo que a aplicação em execução nunca o utilize. Uma compilação em várias fases produz o artefacto numa fase inicial e copia apenas esse para uma fase final limpa, pelo que nenhuma das ferramentas de compilação é incluída.
Remova os pacotes de que a aplicação em execução não necessita. Provavelmente não precisa de um shell, uma vez que a maioria das aplicações inicia o seu processo diretamente e nunca recorre a um durante a execução. Utilitários como o cURL ou o wget são úteis durante a compilação, mas provavelmente não os precisa durante a execução, uma vez que a sua aplicação efetua as suas chamadas de rede através das suas próprias bibliotecas. E tudo o que o cURL tenha descarregado durante a compilação já está integrado na imagem no momento em que esta é distribuída, pelo que não há mais nada para ele descarregar.
Definir as permissões corretamente
Execute o ` container ` como um utilizador não-root. Se um atacante conseguir executar código na sua aplicação, terá os mesmos privilégios com que o ` container ` é executado. A execução como utilizador não-root reduz o alcance dos danos causados por uma intrusão.
Utilize um sistema de ficheiros raiz apenas de leitura. Isto impede que um invasor que já se encontre no sistema escreva ficheiros, instale ferramentas ou modifique o container em tempo de execução. Qualquer elemento que necessite efetivamente de escrever pode, em vez disso, dispor de uma montagem específica com direitos de escrita.
Desative as funcionalidades do Linux que não utiliza. Os contentores iniciam com um conjunto de funcionalidades do kernel que a maioria das aplicações nunca utiliza. CAP_NET_RAW, por exemplo, permite que um processo falsifique pacotes de rede e está ativado por predefinição, mas uma aplicação web típica nunca precisa dele, enquanto um invasor que consiga aceder ao sistema poderia utilizá-lo para falsificar o tráfego na sua rede. Desative as funcionalidades de que não precisa e reative apenas as que forem necessárias. Desativar estas funcionalidades (e reativar apenas as necessárias) impede que um invasor tenha acesso a operações privilegiadas que, de outra forma, estariam ao seu dispor.
Mantenha os ficheiros « secrets » e os ficheiros avulsos fora da imagem
Não inclua « secrets » nas camadas. Um segredo introduzido através de ARG ou COPIAR permanece no histórico da imagem, mesmo que uma camada posterior a elimine, e qualquer pessoa que aceda à imagem pode descompactar as camadas e visualizá-la. Utilize montarias secretas ou Montagens SSH para revelar um segredo numa única etapa de compilação, sem o gravar numa camada.
Manter um segredo isolado das camadas é apenas metade do trabalho. O container em execução ainda precisa do valor, por isso deve ser injetado em tempo de execução a partir de um gestor secrets dedicado (Vault, um gestor secrets na nuvem ou Kubernetes secrets) montado como um ficheiro ou injetado no ambiente, e deve ser renovado periodicamente, em vez de se armazenar credenciais de longa duração em qualquer lugar.
Utilize um .dockerignore ficheiro. Este controla, em primeiro lugar, o que entra no contexto de compilação, pelo que .git, a configuração local e as credenciais isoladas nunca são copiadas para a imagem por uma operação de ampla COPIAR instrução.
Prenda com cuidado
Fixa a base com o «digest», e não com o «tag». A PARTIR do nó:24 resolve-se novamente com o passar do tempo, pelo que duas compilações com um mês de diferença podem obter imagens diferentes, e uma base comprometida pode passar despercebida. Fixação por resumo (@sha256:...) torna a base determinística, pelo que se cria exatamente a imagem que foi testada. Tenha em atenção que, se o seu modelo de aplicação de correções disponibilizar correções sob a forma de novas imagens, um resumo fixado também retém essas correções. Se, em vez disso, conseguir obter uma compilação corrigida da mesma versão que fixou, evita esse problema e mantém a segurança.
Não confie na etiqueta «latest». Há quem pense que significa a versão mais recente e mais estável, mas no Docker trata-se apenas da etiqueta predefinida aplicada à última imagem enviada sem uma etiqueta de versão explícita. Pode remeter para uma imagem mais antiga do que o esperado e pode mudar entre compilações.
Verificar e manter
Gerar um SBOM para cada imagem. Uma « lista de materiais de software » é o inventário completo do que está contido na imagem, incluindo todos os pacotes e versões. É o que lhe permite responder à pergunta «estamos afetados?» no momento em que surge uma nova vulnerabilidade.
Assine cada imagem assim que estiver criada e verifique essa assinatura antes da sua execução, utilizando um controlador de acesso que rejeite qualquer imagem não assinada. Essa cadeia impede que uma imagem adulterada ou não aprovada chegue ao ambiente de produção, mesmo que alguém consiga aceder ao seu registo.
Trate os containers em execução como imutáveis. Assim que uma imagem for implementada, não aplique patches nem reconfigure o container em execução. Crie uma nova imagem, teste-a e volte a implementá-la. O que estiver a ser executado corresponderá sempre ao que criou, testou e assinou, o que elimina o desvio de configuração e torna a reversão tão simples quanto voltar a implementar a imagem anterior.
Verifique as imagens continuamente. Uma imagem que, na semana passada, foi verificada sem problemas pode apresentar hoje uma vulnerabilidade crítica, uma vez que são divulgadas diariamente novas vulnerabilidades relativas a pacotes que já se encontram na mesma. Por isso, a verificação durante a compilação não é suficiente.
Três formas de manter uma imagem base protegida
Manter uma imagem base protegida à medida que são descobertas novas vulnerabilidades é uma tarefa contínua, e existem três formas de a realizar.
Faz tu mesmo
Mantenha a sua própria base reforçada. Escolha uma imagem mínima, elimine o que não precisa e reconstrua-a sempre que um pacote incluído nela apresentar uma vulnerabilidade. Mantém o controlo total, mas isso exige trabalho e manutenção contínuos. Tem de acompanhar as divulgações em todos os pacotes da base e aplicar cada correção manualmente, seja através de backport ou de atualização da versão. Multiplique isso por todas as bases em todos os serviços, e isso acaba por consumir todo o tempo que poderia dedicar a outras tarefas.
Passar para a rede de distribuição renovada de um fornecedor
Algumas plataformas fornecem imagens reforçadas, reconstruídas com base na sua própria distribuição. Migra os seus serviços para essa base, volta a testar para detetar falhas e, em seguida, segue o ritmo de lançamento delas, avançando para um novo resumo a cada correção. Isso acarreta dois custos. A própria migração pode causar falhas em qualquer elemento do qual a sua aplicação dependesse e que o fornecedor tenha removido. E manter-se atualizado significa cair na mesma armadilha de atualização com que qualquer aumento de dependência se depara, em que uma nova versão principal pode alterar os caminhos dos pacotes, mudar as predefinições e danificar um Dockerfile que estava a funcionar. Se fixar um resumo por motivos de estabilidade, não estará a receber as mesmas correções que o levaram a adotar a ferramenta.
Deixa que uma ferramenta aplique uma correção à versão base que já estás a utilizar
Alguns fornecedores permitem que mantenha a sua versão atual, disponibilizando compilações corrigidas da mesma versão, em vez de passar para uma nova imagem. Recebe uma compilação nova da mesma versão com a vulnerabilidade CVE corrigida, que pode adotar através da revisão e integração, tal como qualquer outra alteração, sem necessidade de editar a imagem em execução. Desta forma, mantém-se na versão que já testou e, ainda assim, corrige a vulnerabilidade.
Como o « Aikido » protege as imagens do Docker
Aikido A equipa de segurança disponibiliza novas compilações corrigidas das mesmas versões da imagem base que já utiliza.

Aikido O Images é um repositório com mais de 2 000 imagens de substituição imediata, nas quais as vulnerabilidades conhecidas de gravidade crítica e elevada presentes na imagem base já foram corrigidas. Cada uma delas é recompilada, corrigida, minimizada e reforçada durante o processo de compilação, para que obtenha uma superfície de ataque mais reduzida e configurações predefinidas mais seguras na imagem base que já utiliza.
Enquanto uma ferramenta de distribuição reconstruída fornece o patch como uma nova imagem para a qual se migra, o Aikido faz o backport da correção para a versão que fixou. Retira a correção da versão mais recente e aplica-a à versão que já está a utilizar, pelo que a alteração é mínima e a imagem continua a funcionar como sempre. Quando não é possível fazer um backport limpo, o Aikido atualiza ou recompila o componente em vez disso. A substituição é uma alteração direta que o AutoFix propõe como um pedido de integração, e cada integração proveniente do docker.aikido.io inclui uma proveniência SBOM, VEX e SLSA.
Continua a aplicar correções a versões cujo desenvolvimento já foi descontinuado pelo autor original, incluindo bases que chegaram ao fim do ciclo de vida, para que possa manter uma versão mais antiga sem ter de arcar com as suas falhas conhecidas e não tenha de atualizar apenas para continuar a estar protegido.
Uma percentagem crescente das correções efetivas aos pacotes nunca recebe um CVE; por isso, se você ou as suas ferramentas consultarem apenas a base de dados CVE, estarão a deixar escapar vulnerabilidades. A aplicação de correções do Aikido é alimentada, em parte, pela IntelAikido , que analisa os registos de alterações e o histórico de commits do upstream para detetar vulnerabilidades que foram discretamente corrigidas no upstream sem que lhes tenha sido atribuído um CVE, pelo que a cobertura não se limita ao que as bases de dados públicas ainda não tiveram tempo de atualizar.
Os pacotes ao nível da aplicação no npm, PyPI, Maven e Go são corrigidos diretamente através das Bibliotecas doAikido , utilizando a mesma abordagem de retroportagem aplicada às suas dependências. Além disso, a Análise de Imagens doAikido Container verifica a existência de pacotes do sistema operativo vulneráveis, dependências, ambientes de execução desatualizados, malware e riscos de licença em imagens de base, comandos do Dockerfile e cargas de trabalho do Kubernetes, de modo a que cada deteção seja apresentada juntamente com o código e o contexto da nuvem.
A equipa responsável por estas imagens passou a integrar a Aikido através da aquisição da Root, a empresa por trás do SlimToolkit (anteriormente DockerSlim), uma das ferramentas de reforço de segurança de imagens de código aberto mais utilizadas. O reforço de segurança de imagens foi o ponto de partida desta equipa, e a ferramenta continua a ser gratuita e está disponível para qualquer pessoa utilizar.
{{walkthrough}}
FAQ
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "TechArticle",
"@id": "https://www.aikido.dev/blog/securing-docker-images#article",
"isPartOf": { "@id": "https://www.aikido.dev/blog/securing-docker-images#webpage" },
"mainEntityOfPage": { "@id": "https://www.aikido.dev/blog/securing-docker-images#webpage" },
"headline": "Securing Docker images: harden, patch, and maintain them",
"description": "Most of a container's vulnerabilities come from the base image. How to harden Docker images, why hardening is ongoing, and how to patch the base you already run.",
"datePublished": "2026-08-28",
"dateModified": "2026-08-28",
"wordCount": 1650,
"timeRequired": "PT8M",
"inLanguage": "en-US",
"author": { "@id": "https://www.aikido.dev/authors/nicholas-thomson#person" },
"publisher": { "@id": "https://www.aikido.dev/#organization" },
"image": { "@id": "https://www.aikido.dev/blog/securing-docker-images#primaryimage" },
"articleSection": "DevSec Tools & Comparisons",
"keywords": [
"securing Docker images",
"Docker image security",
"container image hardening",
"base image vulnerabilities",
"distroless images",
"backporting CVE fixes",
"container vulnerability management",
"non-root container",
"multi-stage builds",
"SBOM"
],
"about": [
{ "@type": "Thing", "name": "Docker image security" },
{ "@type": "Thing", "name": "Container image hardening" },
{ "@type": "Thing", "name": "Vulnerability management" }
],
"mentions": [
{ "@type": "SoftwareApplication", "name": "Docker", "applicationCategory": "DeveloperApplication" },
{ "@type": "SoftwareApplication", "name": "Aikido Images", "applicationCategory": "SecurityApplication", "url": "https://www.aikido.dev/cloud/hardened-images" },
{ "@type": "SoftwareApplication", "name": "Aikido Libraries", "applicationCategory": "SecurityApplication" },
{ "@type": "Thing", "name": "Alpine Linux" },
{ "@type": "Thing", "name": "Debian" },
{ "@type": "Thing", "name": "glibc" },
{ "@type": "Thing", "name": "Node.js" },
{ "@type": "Thing", "name": "SBOM" },
{ "@type": "Thing", "name": "SLSA provenance" },
{ "@type": "Thing", "name": "VEX" },
{ "@type": "Thing", "name": "CVE-2023-4911", "url": "https://nvd.nist.gov/vuln/detail/CVE-2023-4911" },
{ "@type": "Thing", "name": "CVE-2025-4373" }
],
"speakable": {
"@type": "SpeakableSpecification",
"cssSelector": ["h1", "h2"]
}
},
{
"@type": "WebPage",
"@id": "https://www.aikido.dev/blog/securing-docker-images#webpage",
"url": "https://www.aikido.dev/blog/securing-docker-images",
"name": "Securing Docker images: harden, patch, and maintain them",
"description": "Most of a container's vulnerabilities come from the base image. How to harden Docker images, why hardening is ongoing, and how to patch the base you already run.",
"inLanguage": "en-US",
"isPartOf": { "@id": "https://www.aikido.dev/#website" },
"primaryImageOfPage": { "@id": "https://www.aikido.dev/blog/securing-docker-images#primaryimage" },
"breadcrumb": { "@id": "https://www.aikido.dev/blog/securing-docker-images#breadcrumb" },
"datePublished": "2026-08-28",
"dateModified": "2026-08-28"
},
{
"@type": "ImageObject",
"@id": "https://www.aikido.dev/blog/securing-docker-images#primaryimage",
"url": "https://www.aikido.dev/blog/securing-docker-images/hero.png",
"caption": "Securing Docker images"
},
{
"@type": "BreadcrumbList",
"@id": "https://www.aikido.dev/blog/securing-docker-images#breadcrumb",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.aikido.dev" },
{ "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://www.aikido.dev/blog" },
{ "@type": "ListItem", "position": 3, "name": "Securing Docker images", "item": "https://www.aikido.dev/blog/securing-docker-images" }
]
},
{
"@type": "WebSite",
"@id": "https://www.aikido.dev/#website",
"url": "https://www.aikido.dev",
"name": "Aikido Security",
"publisher": { "@id": "https://www.aikido.dev/#organization" },
"inLanguage": "en-US"
},
{
"@type": "Organization",
"@id": "https://www.aikido.dev/#organization",
"name": "Aikido Security",
"url": "https://www.aikido.dev",
"logo": {
"@type": "ImageObject",
"url": "https://www.aikido.dev/logo.png"
},
"sameAs": [
"https://www.linkedin.com/company/aikido-security",
"https://x.com/AikidoSecurity"
]
},
{
"@type": "Person",
"@id": "https://www.aikido.dev/authors/nicholas-thomson#person",
"name": "Nicholas Thomson",
"url": "https://www.aikido.dev/authors/nicholas-thomson",
"jobTitle": "Senior SEO & Growth Lead",
"worksFor": { "@id": "https://www.aikido.dev/#organization" },
"sameAs": [
"https://www.linkedin.com/in/nicholas-gray-thomson/"
]
},
{
"@type": "FAQPage",
"@id": "https://www.aikido.dev/blog/securing-docker-images#faq",
"isPartOf": { "@id": "https://www.aikido.dev/blog/securing-docker-images#webpage" },
"mainEntity": [
{
"@type": "Question",
"name": "What is the most important step to secure a Docker image?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Choosing a small base image. Most of a container's vulnerabilities come from the OS packages the base ships, not the code you wrote, so a smaller base means fewer inherited flaws before you add anything of your own. A distroless or minimal base drops whole classes of vulnerabilities that a full distro image would drag in."
}
},
{
"@type": "Question",
"name": "Should Docker containers run as root?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No, unless something genuinely requires it. If an attacker gets code execution in your app, they inherit whatever privileges the container runs as, and root in the container plus a container escape can mean root on the host. Set a dedicated non-root user in your Dockerfile and drop the Linux capabilities the app never uses."
}
},
{
"@type": "Question",
"name": "What is the difference between a minimal image and a hardened image?",
"acceptedAnswer": {
"@type": "Answer",
"text": "A minimal image ships less, stripping out shells, package managers, and libraries the app doesn't need. A hardened image starts from a minimal base and goes further, applying patched package versions and secure defaults like non-root execution. Minimal shrinks the attack surface, and hardened shrinks it and locks down what's left."
}
},
{
"@type": "Question",
"name": "Do I have to migrate to a new distro to harden my base image?",
"acceptedAnswer": {
"@type": "Answer",
"text": "No. Some hardening tools rebuild images on their own distribution, which means migrating every service and re-testing for breakage. The alternative is to keep the distro and major version you already run and backport fixes to that exact version, which is how Aikido Images works, so you get the patch without the migration."
}
},
{
"@type": "Question",
"name": "Why does a hardened image become vulnerable again over time?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Because new vulnerabilities are disclosed against packages already inside it. Nothing in the image changed, but the list of known flaws in its packages keeps growing. Hardening is an ongoing job rather than a one-time pass."
}
},
{
"@type": "Question",
"name": "Can a secret end up inside a Docker image by accident?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes, and it is a common mistake. A secret pulled in with ARG or COPY stays in the image history even if a later layer deletes it, so anyone who pulls the image can unpack the layers and read it. Use build-time secret mounts during the build, and inject runtime secrets from a secrets manager rather than baking them into the image."
}
}
]
}
]
}
</script>

