SBOM
O que escapa aos geradores de SBOM open source
O Syft, o Trivy e o cdxgen são capazes, gratuitos e amplamente usados. Os três constroem uma SBOM a partir dos ficheiros para os quais os aponta: lockfiles, manifestos ou pacotes instalados. É por isso que discordam no mesmo repositório, e por isso que nenhum deles vê o que o build obteve fora desses ficheiros.
Atualizado a
Como gerar uma SBOM com cada ferramenta
Cada ferramenta precisa apenas de um comando para um diretório de código-fonte ou uma imagem de contentor, com saída em CycloneDX ou SPDX:
# Syft: a source directory or a container image
syft ./my-project -o cyclonedx-json=sbom.cdx.json
syft my-image:latest -o spdx-json=sbom.spdx.json
# Trivy: a filesystem or a container image
trivy fs --format cyclonedx --output sbom.cdx.json .
trivy image --format spdx-json --output sbom.spdx.json my-image:latest
# cdxgen: the current directory, optionally with a project type
cdxgen -o bom.json .
cdxgen -t js -o bom.json . Os comandos são a parte fácil. O que acaba no ficheiro depende do que cada ferramenta lê, e não leem as mesmas coisas.
O que cada ferramenta lê
| Ferramenta | Diretório de código-fonte | Imagem de contentor | A ter em conta |
|---|---|---|---|
| Syft | Um conjunto predefinido de catalogers para diretórios, que lê as dependências declaradas | Um conjunto predefinido de catalogers para imagens, que lê os pacotes instalados | Os catalogers são escolhidos pelo tipo de análise. syft cataloger list mostra quais são executados, e --select-catalogers acrescenta-os ou remove-os. |
| Trivy | Lockfiles; para Node.js, package-lock.json, yarn.lock, pnpm-lock.yaml e bun.lock |
Para Node.js, ficheiros package.json em node_modules |
Deixa de fora as dependências de desenvolvimento, a menos que passe --include-dev-deps. |
| cdxgen | Primeiro os lockfiles, que incluem dependências de desenvolvimento; para Node.js, analisa também as importações no código | Suportado | Defina o tipo de projeto com -t para limitar o que procura. |
Porque discordam no mesmo repositório
Aponte os três para o mesmo commit e obtém três listas diferentes. Nenhum está avariado. Cada um segue as suas próprias regras documentadas:
- Sem lockfile, sem dependências. O Express 5.2.1 não faz commit de nenhum lockfile. Num checkout limpo, uma ferramenta que resolve dependências a partir de lockfiles ou de pacotes instalados não tem nenhum dos dois, pelo que as dependências npm declaradas em
package.jsonnunca chegam à SBOM. Escreve na mesma um documento válido com o que mais tiver reconhecido. - Instalado ou declarado. Ter executado uma instalação antes da análise pode importar mais do que a ferramenta usada. Numa cópia instalada do mesmo repositório, uma definição de cataloger do Syft decide se os pacotes npm instalados aparecem sequer.
- Dependências de desenvolvimento. O Trivy deixa-as de fora por defeito e o cdxgen inclui-as, pelo que o mesmo lockfile dá duas respostas a "o que há neste projeto".
- Nomes e versões. As ferramentas identificam alguns componentes com tipos de package URL diferentes, ou fixam uma GitHub Action a um SHA de commit onde outra reporta uma tag. Uma consulta de vulnerabilidades com o identificador errado dá uma resposta errada com toda a confiança.
- Nenhum manifesto. O repositório anthropics/claude-code não tem manifesto de dependências, e o seu pacote npm encapsula um binário pré-compilado. O que cada ferramenta devolve diz mais sobre a ferramenta do que sobre o projeto.
O que escapa a todos: dependências ocultas
O limite mais profundo é partilhado. Um scanner lê o lockfile ou o resultado do build e deduz daí, a posteriori, o que entrou. Tudo o que o build obteve fora desses ficheiros nunca chega à SBOM. São as dependências ocultas:
- Hooks de instalação. Os scripts
preinstallepostinstalldo npm são executados durante a instalação e podem descarregar mais código. Foi assim que o worm Shai-Hulud foi executado. - Scripts de build, como os scripts de build de Rust que descarregam aquilo de que precisam durante o build.
- Imagens base e as respetivas camadas do sistema operativo num build de contentor, que nenhum lockfile de linguagem lista.
- Pacotes restaurados de caches de CI, que podem não corresponder ao lockfile atual. Consulte o que a cache do GitHub Actions esconde.
- Ferramentas de build instaladas por passos de configuração, com as suas próprias árvores de dependências.
- Versões transitivas resolvidas durante o build quando o lockfile não existe, está desatualizado ou não é usado por uma instalação congelada. Consulte dependências transitivas.
Analisar o resultado depois não fecha a lacuna. Um binário acabado, sobretudo código compilado como Rust, deixa o scanner a adivinhar o que entrou nele. Os scanners de SCA comerciais trabalham com os mesmos tipos de ficheiros e partilham os mesmos pontos cegos. O CRACI encontrou pacotes vulneráveis que o Snyk e o Aikido não reportaram, porque os componentes nunca estiveram naquilo que analisaram.
As ferramentas também fazem parte da sua cadeia de abastecimento
Um scanner é executado na sua CI com acesso ao seu código e, muitas vezes, aos seus segredos. Em março de 2026, o aviso de segurança da Aqua Security (CVE-2026-33634) descreveu uma versão maliciosa do Trivy v0.69.4 e tags envenenadas de trivy-action e setup-trivy que roubavam credenciais de runners de CI. Fixe as actions de scanners a SHAs de commit completos e consulte o aviso de segurança para as versões que executa.
Como verificar a sua própria SBOM
- Execute dois geradores sobre o mesmo commit e compare os package URLs que reportam.
- Verifique se o repositório faz commit de um lockfile e se a CI instala a partir dele com uma instalação congelada.
- Analise antes e depois do passo de instalação e compare.
- Compare a lista com o que o registo do seu build mostra a ser descarregado, incluindo passos de configuração e restauros de cache.
Se as listas diferirem, a SBOM que publica depende da ferramenta que por acaso executou, não do que distribuiu.
Registe antes o build
O CRACI vê o tráfego; os scanners não. É um runner de GitHub Actions que vê o tráfego de rede que entra em cada build, pelo que a SBOM do CRACI regista cada pacote que o job trouxe, a qualquer profundidade da árvore, incluindo as dependências ocultas e os pacotes restaurados de caches de CI. Não há nenhum diretório para indicar nem cataloger para escolher. Quando um registo não conseguiu ver tudo, por exemplo porque um job permitiu tráfego não monitorizado, a SBOM indica-o com o seu estado de completude.
Registar também importa porque os builds raramente são reprodutíveis. Faça o build do mesmo commit duas vezes seguidas e o gestor de pacotes pode resolver e instalar por outra ordem, pelo que o segundo build pode conter pacotes diferentes. Só a SBOM registada durante o build que produziu uma versão prova o que essa versão contém.
Mantenha o Syft ou o Trivy para imagens e binários de terceiros que não construiu. Para as suas próprias versões, consulte SBOM durante o build ou marque uma demo para comparar uma SBOM registada com a da sua ferramenta atual num dos seus repositórios.
Geradores de SBOM open source: perguntas frequentes
O que é melhor para SBOM, o Syft ou o Trivy?
Foram feitos para tarefas diferentes. O Syft é um gerador de SBOM dedicado, com muitos catalogers e atestações assinadas; o Trivy é um scanner de segurança que escreve SBOM como um dos seus resultados. Ambos leem os ficheiros que têm à frente, pelo que, no mesmo repositório, a maior diferença costuma ser se foi feito commit de um lockfile e se as dependências foram instaladas antes da análise.
Porque é que a minha SBOM não mostra dependências?
Na maioria das vezes, porque o repositório não faz commit de nenhum lockfile e nada foi instalado antes da análise. Um gerador que lê lockfiles ou pacotes instalados fica então sem nada para ler, e escreve na mesma uma SBOM válida. Faça commit do lockfile ou analise depois do passo de instalação.
O Trivy inclui as dependências de desenvolvimento na SBOM?
Não por defeito. A documentação do Trivy para Node.js diz que não reporta dependências de desenvolvimento a menos que passe --include-dev-deps. O cdxgen, pelo contrário, analisa lockfiles e inclui dependências de desenvolvimento. Só por esta razão, duas ferramentas podem discordar sobre o mesmo projeto.
Posso confiar numa SBOM de um gerador open source?
Quanto ao que leu, sim. A questão é o que não leu: caches, ferramentas de build, descargas, scripts de instalação e binários sem metadados de pacotes. Trate uma SBOM obtida por análise como uma descrição dos ficheiros para os quais apontou a ferramenta, não do build que produziu a sua versão.
Qual é a melhor ferramenta de SBOM?
Para o software que constrói, a SBOM mais completa vem de registar o build em vez de analisar ficheiros. O CRACI regista cada pacote que cada job de GitHub Actions obtém, incluindo de caches, e encontrou pacotes vulneráveis que o Snyk e o Aikido não reportaram. Para imagens e binários de terceiros que não construiu, um scanner como o Syft ou o Trivy continua a ser a escolha prática.
Coloque uma SBOM registada ao lado da do seu scanner
Execute um workflow de GitHub Actions no CRACI e compare a SBOM dos pacotes obtidos com o que o Syft, o Trivy ou o cdxgen reportaram.
Marcar demo