Pular para o conteúdo
>_ITDITDPlataforma de Segurança Web

Guias de Segurança

osv-scanner na prática — pnpm, ignorar CVEs, modo offline e os erros que aparecem

As dúvidas do segundo dia: suporte a pnpm-lock.yaml, ignorar um CVE pelo osv-scanner.toml, as três flags offline e o erro que elas causam, os códigos de saída 0/1/127/128 no CI e as flags renomeadas da v1 para a v2.

Publicado 2026-09-04 Atualizado 2026-10-06 Última verificação 2026-10-06 11 min de leitura

Para quem é: pessoas que já instalaram o osv-scanner e esbarraram em problemas. Isto cobre as dúvidas do segundo dia, não a instalação. Tudo aqui segue a documentação oficial.

Apontando para um lockfile

# a single lockfile
osv-scanner scan source -L pnpm-lock.yaml
 
# walk a directory
osv-scanner scan source -r ./my-project/

Quando o formato não pode ser deduzido pelo nome do arquivo, prefixe o caminho com o parser a usar:

# parse an oddly named file as requirements.txt
osv-scanner scan source -L 'requirements.txt:/path/to/extra-requirements.txt'
 
# path containing a colon — lead with a bare ':' to keep filename inference
osv-scanner scan source -L ':/path/to/my:projects/package-lock.json'

Por que o lockfile e não o manifesto

Um manifesto (package.json e similares) registra a faixa que você pediu, não o que de fato foi instalado. Um lockfile traz versões exatas e resolvidas, então a varredura corresponde ao que realmente está na árvore. Julgar uma faixa e torcer é uma evidência bem mais fraca.

Como verificar o seu próprio ambiente

Quando os resultados parecem errados, passe por estas cinco verificações antes de adicionar mais flags. Cada uma só inspeciona o seu próprio projeto.

1

Verifique a versão

Rode osv-scanner --version. A v2, lançada em 2025, mudou o formato dos comandos e vários nomes de flags, então instruções escritas para a v1 muitas vezes falham do jeito que estão. A documentação oficial agora é voltada para a v2.
2

Verifique o que ele leu

O log da execução mostra cada arquivo lido e quantos pacotes encontrou nele. Confirme que os lockfiles esperados estão listados e que as contagens não estão suspeitamente baixas. Para o inventário completo, use --format json --all-packages (--all-packages só funciona com saída JSON).
3

Verifique o código de saída

Logo após a execução, use echo $? no bash ou $LASTEXITCODE no PowerShell. A tabela abaixo dá os significados.
4

Verifique se a configuração realmente valeu

Um osv-scanner.toml só se aplica aos arquivos do diretório onde ele está; ele não se propaga para subdiretórios. Num monorepo varrido com -r, coloque um ao lado de cada lockfile ou passe um único arquivo para tudo com --config.
5

Verifique onde fica o banco offline e a idade dele

O banco de dados local é lido de OSV_SCANNER_LOCAL_DB_CACHE_DIRECTORY, se definido; senão, do diretório de cache do usuário e, depois, do diretório temporário do sistema. Dentro dele, os arquivos seguem osv-scanner/<ecosystem>/all.zip. Se as datas de modificação forem antigas, o seu veredito também é.

Códigos de saída e como o CI deve tratá-los

Código de saídaSignificado oficialNo CI
0Pacotes encontrados, nenhuma vulnerabilidade conhecida casouPassa
1Pacotes encontrados, vulnerabilidades casaramFalha (um achado: corrija ou ignore com validade)
127Erro geralFalha (a própria varredura quebrou)
128Nenhum pacote encontrado (nada legível foi pego)Falha (corrija o caminho ou adicione o lockfile)

A documentação reserva 1–126 para resultados relacionados à varredura e 129–255 para erros não relacionados aos resultados. Dividir o tratamento no CI em três — 0 passa, 1 é um achado, qualquer outro é uma varredura quebrada — torna as falhas muito mais rápidas de diagnosticar.

Ignorando uma vulnerabilidade específica

Coloque um osv-scanner.toml no diretório que está sendo varrido:

[[IgnoredVulns]]
id = "GHSA-xxxx-xxxx-xxxx"
ignoreUntil = 2026-12-31
reason = "Feature is not used and the code path is unreachable; re-evaluate at the December inventory"
  • id (obrigatório): o identificador da vulnerabilidade
  • ignoreUntil (opcional): depois dessa data ela volta a ser reportada
  • reason (opcional): escreva mesmo assim — para a próxima pessoa, que geralmente é você

--config=/path/to/config.toml substitui os arquivos por diretório e vale em todo lugar. Note que ignorar uma vulnerabilidade também ignora as tratadas como aliases dela.

Dê a toda exceção uma data de validade em vez de removê-la para sempre

Uma entrada sem ignoreUntil é um item que some permanentemente e que ninguém revisita. A nossa regra: toda exceção tem uma validade e um motivo — quando a data passa ela volta, então a decisão adiada não pode ser esquecida em silêncio. Exceções sem prazo adicionadas para calar o CI são exatamente o que vira um incidente seis meses depois.

Modo offline: três flags, três funções

É aqui que mora a maior parte da confusão.

FlagO que faz
--offlineTotalmente offline. Julga contra um banco de dados local baixado antes, não o atualiza e não envia nenhuma informação do projeto ou das dependências para lugar nenhum
--offline-vulnerabilitiesSó a correspondência de vulnerabilidades é offline; outros trabalhos (como a resolução transitiva) ainda podem usar a rede
--download-offline-databasesPermite baixar/atualizar o banco local — só faz efeito quando uma flag offline também está definida

--offline

totalmente offline; sem atualização do banco, nada enviado

--offline-vulnerabilities

só a correspondência é local; outros trabalhos podem usar a rede

--download-offline-databases (inerte sozinha)

precisa de uma das anteriores → sozinha você recebe "databases can only be downloaded when running in offline mode"

As três flags offline. --download-offline-databases não faz nada sozinha, o que causa o erro que as pessoas pesquisam.

Os erros e o que os causa

  • databases can only be downloaded when running in offline mode → --download-offline-databases foi passada sozinha; ela precisa de uma flag offline junto
  • --offline ainda sem banco de dados local → você recebe um erro dizendo que o banco está faltando; a primeira execução precisa baixá-lo
  • no package sources found → nada naquele caminho foi reconhecido como lockfile ou manifesto; indique-o com -L ou percorra com -r

Escolhendo sem chutar

  • Execução isolada da rede → --offline (mais --download-offline-databases na primeira execução)
  • Só os dados de vulnerabilidade precisam ficar locais → --offline-vulnerabilities
  • Fixar onde o banco fica → a variável de ambiente OSV_SCANNER_LOCAL_DB_CACHE_DIRECTORY
  • Depuração → rode primeiro sem flags, depois afunile

Quando flags de um artigo da v1 não funcionam

Muitos resultados de busca foram escritos para a v1. As principais mudanças listadas no guia oficial de migração:

v1v2
--experimental-offline--offline
--experimental-download-offline-databases--download-offline-databases
--experimental-call-analysis--call-analysis
--experimental-licenses e relacionadasunificadas em --licenses
--docker / -D (containers)osv-scanner scan image <image>
--json--format=json
--skip-git--include-git-root (sentido invertido)

osv-scanner <dir> ainda funciona como atalho para osv-scanner scan source <dir>. Escrever scan source por extenso em scripts deixa a intenção clara para o próximo leitor.

Erros comuns e como corrigi-los

Erros comuns

  • O CI trata "qualquer código de saída exceto 1" como sucesso
  • || true adicionado para fazer as falhas sumirem
  • Um único osv-scanner.toml na raiz do repositório, presumindo que cobre os subdiretórios
  • Só o package.json commitado, sem lockfile
  • Presumir que --offline ainda resolve as dependências transitivas de um pom.xml
  • Exceções escritas sem ignoreUntil

A correção

  • Passe só com 0, para que o 128 (nada lido) não fique verde
  • Cale achados individuais com exceções que expiram
  • Coloque um arquivo em cada diretório ou aplique um para tudo com --config
  • Commite o lockfile (em JavaScript: package-lock.json, pnpm-lock.yaml, yarn.lock ou bun.lock)
  • A resolução transitiva fica desativada offline; se a rede for permitida, use --offline-vulnerabilities
  • Sempre adicione uma data e um motivo, e decida de novo quando a data chegar

Um pom.xml do Maven não lista todas as versões resolvidas como um lockfile faz. Por padrão, o osv-scanner calcula o grafo transitivo usando o resolvedor do deps.dev (ou o Maven Central com --data-source=native). Isso precisa da rede e é pulado com --offline e --no-resolve. Numa execução totalmente isolada da rede, espere que os resultados cubram só as dependências escritas diretamente no pom.xml.

Um exemplo real: por que o Log4Shell foi difícil de responder

Quando o Log4Shell (CVE-2021-44228) apareceu em dezembro de 2021, muitas organizações não conseguiram dizer rapidamente se eram afetadas. Elas nunca tinham adicionado o Log4j por conta própria; ele chegava por meio de frameworks e outras bibliotecas. A orientação da CISA pedia que as organizações levantassem de forma abrangente o software instalado e o comparassem com a lista de software afetado.

Aplicado ao osv-scanner, isso significa verificar duas coisas:

  • As dependências transitivas estão de fato sendo lidas: lockfiles onde o ecossistema os tem e, no Maven, uma execução com a resolução ativada (não offline, sem --no-resolve)
  • O inventário realmente contém as bibliotecas que chegam indiretamente — imprima-o com --format json --all-packages e confira

Conseguir responder "somos afetados?" em minutos no dia da divulgação depende de ter esse inventário certo de antemão.

Em que difere das ferramentas vizinhas

FerramentaDados que lêNo que é boa
osv-scannerOSV.devVários ecossistemas, por lockfile, pode rodar offline
npm audit / pnpm auditBanco de avisos do npmImediato para projetos npm, nada extra para instalar
DependabotGitHub AdvisoryAbre PRs de atualização — propõe a correção, não só o achado
TrivyVários (incl. OSV)Imagens de container e pacotes do SO, além das dependências do app

Escolher exatamente uma é o erro. Bancos de dados diferentes revelam coisas diferentes. Nós rodamos o pnpm audit como verificação automática diária e usamos o osv-scanner para verificações entre lockfiles.

A visão deste site: um scanner não avisa que o seu pin ficou desatualizado

Um problema só aparece na operação real. Quando você fixa uma dependência transitiva numa versão exata com overrides, esse pacote deixa de receber atualizações de patch — e um scanner só se manifesta quando existe uma vulnerabilidade conhecida. Então "a versão que você congelou agora está velha" é um estado que ninguém reporta. Passamos por isso três vezes antes de adicionar a nossa própria verificação diária, que compara cada pin com o patch mais recente da sua linha principal. Um scanner mostra as vulnerabilidades conhecidas hoje; condições que tendem a deixar você exposto depois precisam de outro mecanismo.

Fontes

Leia a seguir

FAQ

QO osv-scanner suporta pnpm-lock.yaml?
A

Sim. Lockfiles de npm, yarn e pnpm são todos suportados. Aponte para um diretamente com `osv-scanner scan source -L pnpm-lock.yaml` ou percorra uma árvore com `-r`.

QComo ignoro um único CVE?
A

Coloque um `osv-scanner.toml` no diretório varrido e adicione uma entrada `[[IgnoredVulns]]` com o `id`. Você também pode definir `ignoreUntil` (uma data de validade) e `reason`, para que a exceção registre quando e por quê, em vez de sumir para sempre. Passar `--config=/path/to/config.toml` substitui os arquivos por diretório e vale para tudo.

QPor que recebo 'databases can only be downloaded when running in offline mode'?
A

Porque `--download-offline-databases` só faz efeito quando uma flag offline também está definida — ela não pode ser usada sozinha. Combine-a com a flag offline quando quiser que o banco de dados local seja baixado como parte da execução.

QSe eu já tenho npm audit e Dependabot, preciso do osv-scanner?
A

Eles leem bancos de dados diferentes e cobrem terrenos diferentes. O npm audit usa o banco de avisos do npm e só serve para npm; o Dependabot propõe principalmente atualizações no GitHub; o osv-scanner lê o OSV.dev em vários ecossistemas (npm, PyPI, Go, Maven e outros), trabalha por lockfile e pode rodar totalmente offline. É normal um pegar algo que o outro deixa passar, então trate-os como funções diferentes em vez de escolher um.

QComo o CI deve tratar os códigos de saída do osv-scanner?
A

Segundo a documentação oficial: 0 significa que pacotes foram encontrados e nenhum casou com uma vulnerabilidade conhecida, 1 significa que vulnerabilidades foram encontradas, 127 é um erro geral e 128 significa que nenhum pacote foi encontrado. Trate só o 0 como sucesso. Uma regra como 'tudo menos 1 passa' transforma o 128 — nada foi varrido — num sinal verde.

QPor que --experimental-offline ou --docker de artigos antigos não funcionam?
A

Foram renomeados ou movidos na v2. O guia oficial de migração mapeia --experimental-offline para --offline, --experimental-download-offline-databases para --download-offline-databases, --docker para o comando `osv-scanner scan image` e --json para `--format=json`. Rode `osv-scanner --version` primeiro para ver qual versão principal você tem.