Skip to main content

Corrija vulnerabilidades em projetos Maven

Escrito por
Maven feature

14 de setembro de 2020

0 minutos de leitura

Maven ainda é o sistema de build mais usado no ecossistema Java. De acordo com o relatório JVM de 2020, Maven é a principal ferramenta de build do ecossistema, com dois terços de participação.

Por isso, é importante saber como Maven funciona. Por exemplo, se você encontrar vulnerabilidades no seu projeto Maven com o Snyk, como poderá corrigi-las? Neste artigo, explico como corrigir vulnerabilidades em bibliotecas de terceiros ao usar Maven, mesmo quando a solução não é óbvia.

Como encontrar vulnerabilidades

Se você usa Maven para criar seu projeto e gerenciar as dependências, há várias maneiras de analisar seus projetos com o Snyk. Isso independe da linguagem de programação usada: pode ser Java, Kotlin, Scala, Groovy ou qualquer outra linguagem criada para a Java Virtual Machine (JVM).

Você pode analisar seu projeto Maven em busca de vulnerabilidades com o Snyk usando:

Usando a CLI como exemplo, o Snyk mostra se e como você pode corrigir vulnerabilidades atualizando as dependências de nível superior. No entanto, se não houver uma versão aprimorada dessas dependências, o Snyk mostra se há uma versão mais recente da dependência subjacente que corrige as vulnerabilidades.

Saída do terminal listando vulnerabilidades de software, incluindo desserialização de dados não confiáveis e negação de serviço, com orientações para atualização.

Como corrigir vulnerabilidades em dependências de nível superior

A maneira mais simples de corrigir uma vulnerabilidade encontrada pelo Snyk é alterar a biblioteca de nível superior, se possível. Se a biblioteca não tiver dependências subjacentes, é bem simples: basta atualizar para uma versão mais recente que não tenha o problema específico. O mesmo vale quando uma dependência subjacente apresenta um problema, mas já existe uma versão mais recente da dependência de nível superior sem esse problema.

Há algumas maneiras de alterar a versão. Primeiro, descubra onde ela está especificada. No caso das dependências de nível superior, geralmente você encontra a versão em um destes locais:

  • em um pom pai

  • em uma propriedade

  • diretamente na dependência

Pom pai

Se a dependência que você precisa atualizar estiver definida em um pom pai, primeiro procure uma versão mais recente desse pom. No caso do Spring Boot, por exemplo, se já houver uma versão mais recente do pom pai, considere atualizá-lo e veja se isso resolve o problema. Assim, você atualiza o conjunto inteiro de dependências que, na maioria dos casos, funciona melhor em conjunto do que quando apenas uma dependência é atualizada. Se não puder trocar ou alterar o pom pai, use a abordagem direta.

<parent>
   <groupId>io.snyk</groupId>
   <artifactId>demo-parent</artifactId>
   <version>1.0.4.RELEASE</version>
</parent>

Propriedades

Se uma propriedade for usada, atualize-a primeiro. Isso pode atualizar outras dependências também, mas, assim como no caso do pom pai, há um bom motivo para isso. Se as bibliotecas são lançadas em conjunto, é provável que funcionem melhor juntas quando usam a mesma versão.

<dependency>
  <groupId>org.eclipse.collections</groupId>
  <artifactId>eclipse-collections</artifactId>
  <version>10.4.0</version>
</dependency>

Diretamente na dependência

Por fim, a dependência pode estar declarada na seção dependencies do arquivo pom do Maven. Nesse caso, você especifica o groupId, o artifactId e, muitas vezes, a versão. Se a versão estiver declarada ali, basta atualizá-la. Caso contrário, você pode adicioná-la.

Observe que esta é a forma mais específica de declarar a versão da dependência e que ela substituirá todas as outras formas de definir a versão.

<dependency>
  <groupId>org.eclipse.collections</groupId>
  <artifactId>eclipse-collections</artifactId>
  <version>10.4.0</version>
</dependency>

Como corrigir dependências subjacentes

Digamos que ainda não exista uma versão mais recente da dependência de nível superior, mas que uma das dependências subjacentes tenha um problema que você precisa corrigir. A CLI já avisou que há uma versão mais recente dessa dependência subjacente que resolve o problema.

Bill of Materials

Muitos frameworks usam um Bill of Materials (BOM) para gerenciar dependências subjacentes. Um BOM é um tipo especial de POM usado para controlar as versões das dependências de um projeto e oferecer um local central para defini-las e atualizá-las.

Quando for necessário substituir uma dependência subjacente em um framework como o Spring Boot, verifique se ela faz parte de um BOM. Se fizer, confira se já existe uma versão mais recente desse BOM e atualize a versão. No Spring Boot e em muitos outros frameworks conhecidos, as versões do BOM são especificadas como uma propriedade. Você pode substituir essa propriedade no seu próprio arquivo POM do Maven adicionando uma propriedade.

No exemplo abaixo, substituo o BOM do Jackson no meu projeto Spring Boot:

<properties>
    <jackson.version>2.10.2.20200130</jackson.version>
</properties>

Gerenciamento de dependências

Em um POM do Maven, é possível excluir e incluir dependências subjacentes específicas ao declarar uma dependência de nível superior. No entanto, isso pode causar problemas quando duas bibliotecas compartilham a mesma dependência subjacente. Uma boa prática no Maven é reunir essas declarações na seção de gerenciamento de dependências. Essa seção permite que os autores do projeto especifiquem diretamente as versões dos artefatos a serem usados quando forem encontrados em dependências transitivas. Além do exemplo abaixo, a documentação explica claramente como usar dependencyManagement:

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.yaml</groupId>
           <artifactId>snakeyaml</artifactId>
           <version>1.26</version>
       </dependency>
   </dependencies>
</dependencyManagement>

Conclusão

Como você pode ver, há várias maneiras de reduzir os riscos de segurança em dependências de código aberto em um projeto baseado em Maven. Mesmo quando não há uma correção direta por meio da atualização de uma dependência de nível superior, você pode filtrar uma dependência transitiva subjacente e substituí-la por uma versão mais recente disponível. A análise do Snyk Open Source informa qual versão você precisa atualizar. Este artigo mostra como configurar tudo corretamente no seu projeto Maven.

Comece a resolver desafios de capture the flag

Aprenda a resolver desafios de capture the flag assistindo sob demanda ao nosso workshop virtual introdutório.