Suas imagens de container não estão seguras!
Tags: braziliandevs, docker, containers, devops
Published: 2024-03-20 21:53:30

Não vale a pena chover no molhado, então não vou perguntar se você já sabe o que é um container, a pergunta agora é outra: Você sabe se o seu container está seguro? NÃO?!? Então chega junto que eu vou te mostrar uma parada. 

Antes de começar precisamos passar por conceitos importantes, porque assim poderemos enxergar o valor real de ferramentas open source focadas em segurança, como as imagens da Chainguard.

<h3>O que é uma vulnerabilidade de software?</h3>

Uma vulnerabilidade de software pode ser descrita como uma brecha de segurança contida dentro de um código fonte. Essa brecha pode ser aproveitada por pessoas mal intencionadas para acessar e manipular o software de uma forma nociva, causando um impacto negativo em empresas e/ou nos usuários que façam o uso desse software.

Essas vulnerabilidades não podem ser postas como responsabilidade de um único indíviduo dentro de uma equipe de desenvolvimento, até porque podem surgir em diferentes etapas do desenvolvimento, desde a sua concepção, passando pelo desenvolvimento do código até chegar ao deploy e a sustenção do software. E como você deve ter imaginado, existem diversas vulnerabilidades conhecidas no mercado atualmente, porém nem todas são iguais. 

<h3>O que são CVEs e CVSSs?</h3>

Para saber mais sobre as vulnerabilidades existentes e como metrificá-las utilizamos esses dois "queridões", o CVE *(Common Vulnerabilities and Exposures)* e o CVSS *(Common Vulnerability Scoring System)*.

O CVE é um sistema público que nos ajuda a padronizar a documentação das vulnerabilidades que podemos nos deparar ao longo da nossa carreira, como lidar com novas vulnerabilidades não é do escopo do CVE, porém caso seja encontrada uma solução e ela se torne pública, essa vulnerabilidade terá uma documentação mais ampla, contando com formas de mitigar essa vulnerabilidade, quais foram os vetores e quais foram os danos causados. 

O CVE possui um processo para que as vulnerabilidades sejam documentadas, e consequentemente se tornem públicas, ele funciona da seguinte maneira: 

1. Uma pessoa, ou organização, descobre uma vulnerabilidade; 
2. A vulnerabilidade é reportada para uma empresa participante do programa CVE; 
3. A empresa solicita uma identificação para essa vulnerabilidade, essa identificação segue um padrão de nomeclatura, CVE + ano de publicação da vulnerabilidade + Identificador único, por exemplo, CVE-2021-25276;
4. O ID é reservado e será tratado internamente, porque nessa etapa a agência que cuida dos registros numéricos ainda não está preparada para publicar essa nova CVE, essa agências são chamadas de CNAs (CVE Numbering Authorities);
5. A empresa publica os detalhes da vulnerabilidade, como a causa do problema, o tipo de vulnerabilidade, o impacto etc.;
6. Por fim, a CVE é publicada assim que contém os requisitos mínimos para que possa se tornar pública, esse registro público é feito por uma CNA.

O CVSS utiliza algumas métricas para calcular o grau de severidade, como as métricas B *(Base metrics)*, BE *(Base and Environmental metrics)*, BT *(Base and Threat metrics)* e a BTE que combina todas as métricas, essas diferentes métricas servem para propósitos diferentes, que são os seguintes:

B -> São métricas que representam as características intrínsecas de uma vulnerabilidade que são classificadas como constantes, seja ao longo do tempo e independente do ambiente;

T -> São as características de uma ameaça que podem variar ao longo do tempo, mas não variam necessariamente entre ambientes;

E -> São características de vulnerabilidades que estão dentro do contexto do ambiente em que as aplicações estão sendo executadas.

Essas métricas ajudam a computar um score melhor e mais assertivo quando se trata de vulnerabilidades, aliás, vamos falar sobre o score das vulnerabilidades.

O score (ou pontuação) de cada vulnerabilidade é o que a define como uma vulnerabilidade crítica ou de baixo risco. Para que isso seja possível temos métricas que estão dentro de cada base que citei acima, passando por diversos contextos como vetor do ataque, a complexidade do ataque, se já existem técnicas maduras o suficiente para ajudar nesse ataque, e até mesmo métricas para indicar se o ambiente atacado possui dados sensíveis que não podem ser perdidos ou danificados, além de outras métricas que também são muito importantes para justificar o score. 

A junção de várias métricas e seus resultados é o que constitui o score final da vulnerabilidade, atualmente o score atualizado do CVSS 4.0 é o seguinte:

![Tabela de scores CVSS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/72dnb2wskcrhkusrfl7j.png)

<h3>Como eu posso identificar essas vulnerabilidades?</h3>

Agora que passamos pelas vulnerabilidades, é normal se questionar sobre como podemos encontrá-las em nossos projetos pessoais, ou até mesmo em sistemas empresariais. Para isso contamos com a ajuda de diversas ferramentas de scan de vulnerabilidades, como o [trivy](https://trivy.dev/) e o [grype](https://github.com/anchore/grype?tab=readme-ov-file), eles podem nos ajudar a buscar vulnerabilidades em uma imagem de um container, em um repositório, um filesystem, imagens de máquinas virtuais etc., ambos servem para o mesmo propósito, porém existem algumas particularidades entre as duas ferramentas que não cabem no assunto do texto, sugiro que deem uma olhada nas documentações para encontrar o que melhor satisfaz sua demanda. 

Um exemplo de como utilizar o trivy pode ser encontrado em sua [documentação](https://github.com/aquasecurity/trivy), o mesmo existe para o [grype](https://github.com/anchore/grype), mas gostaria de trazer aqui um exemplo do trivy e como essas vulnerabilidades são apresentadas para nós. 

O trivy faz o scan dos pacotes que são utilizados dentro dos softwares, esses são conhecidos como SBOMs *(Software Bill of Materials)* e servem como uma "receita de bolo" para se criar um software, portanto lista todos os pacotes e dependências do projeto, isso será analisado pelo trivy; o trivy pode scanear o objeto buscando CVEs conhecidas através da leitura de bancos de dados que contém essas informações sobre as CVEs.  

O exemplo mais simples que podemos demonstrar é o scan de uma imagem que está contida no registry do Docker, o famoso docker hub. Para isso vamos pegar uma imagem muito utilizada, a do servidor NGINX, podemos executar essa ação com o seguinte comando:

```SHELL
trivy image nginx:latest
```

Esse comando faz um scan de uma imagem de container para checar todas as vulnerabilidades, a saída do comando padrão é uma tabela contendo as informações da imagem que foi identificada, o número total de vulnerabilidades e quais os graus de risco de cada:


![Output do trivy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slxexilgjrha0iq26v20.png)

Abaixo dessa saída, a ferramenta nos oferece uma tabela com todas as CVEs detalhadas e o status de cada, se já foram solucionadas ou não, o grau de risco, os pacotes que são afetados por essa CVE, e outras informações referentes a esse contexto. 


![Tabela do output do trivy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1hb8upfg79i7geg5adf6.png)

Aqui podemos ter uma ideia da quantidade de vulnerabilidades que uma imagem "padrão" pode conter, são 149 vulnerabilidades conhecidas, contendo  28 de alto risco e 2 críticas, imagina a bagaceira que pode acontecer em um possível ataque. Complicado, né?

<h3>Cortando o mal pela raiz</h3>

Agora que chegamos no final do caminho (será?) temos uma questão a ser resolvida: Como podemos diminuir as vulnerabilidades das nossas imagens de container? 

A resposta é simples: Usando imagens confiáveis (durrrr)!

Brincadeiras à parte, hoje temos algumas soluções no mercado que se propõe a criar imagens distroless, que são imagens que não possuem um distribuição Linux convencional por trás da imagem, diminuindo significativamente a quantidade de possível vulnerabilidades que uma imagem pode conter, visto que diversos CVEs apontam que a causa do problema são pacotes de software contidos dentro de um SO que serve como base para nossas imagens, e o pior de tudo, esses pacotes muitas vezes não são necessários para a nossa aplicação em si. 

Uma dessas opções é oferecida pela [Chainguard](https://www.chainguard.dev/), uma empresa que tem como objetivo a segurança do open source, oferecendo imagens seguras para que possamos trabalhar com containers sem termos que nos preocupar tanto com a parte da segurança, por exemplo.

As imagens da chainguard são baseadas no Wolfi, um sistema operacional que é desenvolvido pela própria Chainguard. O Wolfi é uma (não)distro de Linux usada para servir de base para imagens seguras, porque não conta com a presença de pacotes "desnecessários" para que uma aplicação possa rodar. 

Todas as imagens da chainguard estão disponíveis no repositório deles no github, exatamente neste repositório aqui -> [Images](https://github.com/chainguard-images/images/tree/main). 

"Nicolas, fala logo das vulnerabilidades da imagem, pelo amor de Deus!! Tem criança chorando aqui!!!", e eu te digo: Calma, mussarelo! Vamos ao que interessa então, vamos passar o trivy na imagem do NGINX da chainguard para checar as vulnerabilidades. 

```SHELL 
trivy image cgr.dev/chainguard/nginx:latest
```

Antes de mostrar o resultado, peço que segure o queixo para não cair, de novo. Segurou? Então se liga no resultado:


![Vulnerabilidades da imagem do NGINX da Chainguard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5akbplhcfqll1oywfais.png)

Sim, nenhuma vulnerabilidade! 

Pronto! Agora você conhece uma alternativa para as suas imagens padrão, uma alternativa segura, performática e enxuta. Lembrando que os projetos da Chainguard são open source, portanto se você quiser e puder contribuir com os projetos, sinta-se livre para checar o repositório deles no github, seja para ajudar em uma issue, abrir uma discussão sobre melhorias, apontar bugs encontrados etc., faça sua parte para que possamos construir um futuro mais seguro e open source. 

Por fim, gostaria de indicar o hub de imagens da chainguard e o site com as documentações pros produtos que eles oferecem. Esse texto foi muito introdutório e mostrou apenas a ponta do iceberg quando se trata de imagens seguras, mas acho que a mensagem foi passada de forma clara: Cuide da segurança das suas imagens! 

Aqui temos o hub das imagens da Chainguard -> [Hub](https://images.chainguard.dev/?category=featured)

Aqui temos a documentação das imagens oferecidas pela Chainguard -> [Docs](https://edu.chainguard.dev/)

Infelizmente os conteúdos relacionados às imagens da Chainguard, seguindo a documentação oficial, estão todos em inglês, mas prometo fazer um esforço para trazer mais conteúdo sobre elas em português.  

Agradeço a atenção e a leitura! Estou disponível para conversar mais sobre o assunto e receber feedbacks sobre o conteúdo deste texto, muito obrigado!

<h3>Bibliografia</h3>

https://edu.chainguard.dev/

https://github.com/wolfi-dev

https://github.com/aquasecurity/trivy

https://juniorjbn.medium.com/o-que-%C3%A9-esse-tal-de-distroless-d1cc5dcd070e

https://gomex.me/blog/distroless/

https://www.akamai.com/blog/security/cves-what-they-are-ways-to-mitigate-their-impact

https://www.first.org/cvss/specification-document#CVSS-v4-0-Scoring

https://www.cve.org/About/Process#CVERecordLifecycle