Como criar SBOMs em Java com Maven e Gradle
31 de outubro de 2022
0 minutos de leituraAo desenvolver aplicações em Java, dependemos muito de bibliotecas e frameworks externos. E cada pacote Java importado provavelmente também depende de outras bibliotecas. Isso significa que muitas vezes não há transparência sobre a quantidade de pacotes Java incluídos na aplicação. Para quem desenvolve, essas dependências aninhadas (transitivas) trazem um problema: provavelmente você não sabe quais são todas as bibliotecas que está usando de fato.
Recentemente, falamos sobre por que e como devemos gerenciar nossas dependências com cuidado. No artigo Boas práticas para gerenciar dependências Java, apresentei as opções e ferramentas disponíveis para definir uma estratégia de gerenciamento de dependências. Mas e quando você entrega sua aplicação Java a um cliente? Como ele sabe quais dependências estão incluídas? E, mais importante, como pode verificar se elas não apresentam vulnerabilidades de segurança? A resposta é uma lista de materiais de software.
O que é uma SBOM?
Uma lista de materiais de software, geralmente chamada de SBOM, é uma relação de todos os componentes de software usados em uma aplicação. A SBOM inclui bibliotecas de código aberto de terceiros, pacotes fornecidos por fornecedores e artefatos próprios desenvolvidos pela organização. Basicamente, você pode pensar nela como uma lista completa dos ingredientes da sua aplicação.
Mas cuidado para não confundir SBOM com a Bill Of Materials (BOM) do Maven. No Maven, uma BOM é um tipo especial de arquivo POM que permite centralizar as dependências de uma aplicação. Na maioria dos casos, essas dependências funcionam bem juntas e devem ser usadas em conjunto, como vemos nas BOMs do Spring.
A SBOM é criada junto com a aplicação para que qualquer usuário ou cliente tenha uma maneira padronizada de descobrir o que ela usa nos bastidores.
Por que devo criar uma SBOM?
Há vários motivos para criar uma SBOM. Para começar, ela traz transparência sobre o que compõe sua aplicação. Na maioria das aplicações Java, de 80% a 90% do binário gerado consiste em outros pacotes Java, como bibliotecas e frameworks.
Hoje em dia, vemos muitos problemas de segurança na cadeia de suprimentos. As dependências que você usa fazem parte da sua cadeia de suprimentos. Portanto, se for encontrado um problema em uma dessas bibliotecas, você precisa saber se uma aplicação está vulnerável. Veja as vulnerabilidades recentes Log4Shell e Spring4Shell, que afetaram alguns pacotes de uso comum. Quando uma SBOM é incluída em cada versão, usuários finais e clientes podem verificar facilmente se foram afetados por vulnerabilidades.
Espera-se que a criação de SBOMs se torne uma prática comum — e, às vezes, até obrigatória — na entrega de software. Por isso, consideramos importante explicar como criar SBOMs para seu projeto Java. É o que faremos no restante deste artigo.
Padrões de SBOM: SPDX e CycloneDX
Atualmente, há vários padrões de SBOM. Os dois mais usados são SPDX e CycloneDX. Ambos permitem apresentar os componentes que sua aplicação contém.
O Software Package Data Exchange (SPDX) é um projeto colaborativo da Linux Foundation que oferece um padrão aberto para comunicar informações de listas de materiais de software, incluindo procedência, licenciamento, segurança e outros dados relacionados. A especificação SPDX é reconhecida como padrão internacional aberto para segurança, conformidade de licenças e outros artefatos da cadeia de suprimentos de software, conforme a norma ISO/IEC 5962:2021.
CycloneDX é um padrão de SBOM da fundação OWASP, desenvolvido para contextos de segurança de aplicações e análise de componentes da cadeia de suprimentos. Ele oferece um inventário de todos os componentes de software próprios e de terceiros. A especificação é abrangente e vai além das bibliotecas de software, incluindo padrões como lista de materiais de software como serviço (SaaSBOM), Vulnerability Exploitability Exchange (VEX) e outros. O projeto CycloneDX oferece padrões em XML, JSON e Protocol Buffers, além de uma ampla coleção de ferramentas oficiais e mantidas pela comunidade que criam ou são interoperáveis com o padrão.
Quando criar uma SBOM em Java
Java é uma linguagem compilada, então você deve criar uma SBOM sempre que gerar uma versão de lançamento da aplicação. Por isso, faz muito sentido criar uma SBOM usando um dos sistemas de build de Java: o sistema baixa todos os pacotes necessários para compilar e gerar sua aplicação. Com um plugin para Maven ou Gradle, você pode criar SBOMs facilmente a cada lançamento do binário, seja em uma única máquina ou como parte do pipeline de CI.
Como criar uma SBOM Java com Maven
Plugin CycloneDX para Maven
Há um plugin CycloneDX disponível no Maven Central e no GitHub que parece ser bem mantido e bastante usado.
Você pode configurar o plugin CycloneDX de várias maneiras. Neste caso, vinculei o objetivo makeAggregateBom do plugin à fase package do Maven. Depois que meu JAR é criado, o plugin gera uma SBOM, considerando a agregação. Ele exclui as dependências de teste e gera a SBOM nos formatos XML e JSON na pasta target.
Todas as dependências, diretas e transitivas, são listadas individualmente na SBOM, como no exemplo abaixo. Neste caso, o pacote jackson-databind foi incluído de forma transitiva na minha aplicação por meio de sprint-boot-starter-web.
Plugin SPDX para Maven (protótipo)
Também há um plugin do Maven para SPDX. No entanto, ele ainda está marcado como protótipo. No exemplo abaixo, usei a versão mais recente (na época da redação deste artigo), com uma configuração semelhante à descrita no README do GitHub. Também vinculei a tarefa de criação da SPDX à fase package, como no exemplo do CycloneDX.
Por padrão, esta versão do plugin salva a saída em /target/site/{groupId}_{artifactId}-{version}.spdx.json. Como a extensão do arquivo já indica, o formato padrão da saída é JSON.
Ao analisar a saída, me surpreendi ao ver que ela continha apenas as dependências de nível superior, e não as transitivas. O plugin está marcado como protótipo, então talvez esse seja o motivo. Também é possível que eu esteja fazendo algo errado. No entanto, a documentação não me deu uma indicação clara.
Ferramenta de linha de comando SPDX para Maven
Outra opção é a ferramenta de linha de comando spdx-sbom-generator. Ela pode gerar SBOMs SPDX para vários gerenciadores de pacotes, incluindo Maven para aplicações Java. No momento, o Gradle não é compatível.
Executar essa ferramenta pela linha de comando, sem parâmetros, na raiz da minha aplicação gera uma SBOM no formato SPDX. Outros formatos de saída, como JSON, também são compatíveis quando se usa um parâmetro.
Essa SBOM gerada parece listar todas as dependências transitivas individualmente, como eu esperava.
Se você quiser criar SBOMs no formato SPDX, recomendo essa ferramenta em vez do plugin protótipo.
Como criar uma SBOM Java com Gradle
Agora, vamos falar do Gradle. Embora seja menos usado que o Maven, o Gradle ainda tem ampla adoção e é, sem dúvida, uma ferramenta de build consolidada no ecossistema.
CycloneDX para Gradle
Há um plugin CycloneDX para Gradle. Assim como o plugin Maven que vimos antes, o plugin para Gradle é publicado pela organização CycloneDX no GitHub e conta com alguns dos mesmos mantenedores do plugin Maven.
Para usar o plugin, basta adicioná-lo ao bloco de plugins no arquivo Gradle:
Você pode configurar o plugin com um bloco cyclonedxBom, como no exemplo abaixo:
Neste exemplo, também adicionei a linha build.finalizedBy('cyclonedxBom') ao final do arquivo Gradle. Assim, o destino cyclonedxBom será chamado automaticamente após o build da aplicação, funcionando de maneira semelhante ao plugin Maven. É claro que cabe a você decidir se e como quer vincular o destino do plugin.
A saída é a esperada e semelhante à que vimos com o plugin Maven. Com a configuração acima, você encontrará as versões JSON e XML da SBOM na pasta build do projeto. Portanto, esse plugin é uma ótima opção para quem usa Gradle e quer criar SBOMs.
SPDX para Gradle
Infelizmente, não encontramos um plugin de fato para criar SBOMs no formato SPDX em projetos Gradle. As ferramentas de linha de comando de terceiros também não estão disponíveis ou não funcionam corretamente com projetos Java baseados em Gradle. Por enquanto, não há uma maneira fácil de gerar SBOMs SPDX para Gradle.
Como criar SBOMs para seus projetos Java
Criar uma SBOM durante o build do projeto Java parece ser uma prática que logo ficará mais popular. Faz muito sentido deixar essa tarefa por conta do sistema de build.
Há plugins para Maven e Gradle que criam SBOMs durante o build da aplicação. Como mostramos acima, esses plugins facilitam a criação de SBOMs junto com os artefatos de build Java.
Comece a participar de desafios de Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.



