Um comando npm install ou pip install pode trazer para o repositório um pacote criado para roubar variáveis de ambiente e chaves de deploy. O ataque por dependência não explora uma falha do seu código: ele abusa da confiança que o build deposita em registros públicos. Equipes que mantêm aplicações em Node, Python, Go, Java, Ruby ou PHP têm uma defesa direta e gratuita: colocar o OSV-Scanner entre o pull request e o merge, com um período de espera para versões recém-publicadas. A ação prioritária é fazer o scan bloquear o pipeline quando a branch introduz algo comprometido, antes que o pacote chegue à branch principal e, a partir dela, ao ambiente de produção.

O problema nas dependências

Typosquatting, dependency confusion e protestware compartilham o mesmo vetor: o desenvolvedor pede um nome de pacote, o resolvedor baixa o que foi publicado e nada no fluxo normal verifica a intenção daquele código. Como o dependências digitais ampliam a superfície de ataque, cada nova biblioteca herdada herda também o risco de quem a publicou. O resultado prático é um backdoor que entra pelo caminho mais legítimo da engenharia de software: o gerenciador de pacotes.

O cenário piora porque a janela entre a publicação de um pacote malicioso e a remoção do registro é curta, mas suficiente. Uma única execução de npm install nesse intervalo executa scripts de instalação no contexto da máquina do desenvolvedor, com acesso a tokens do provedor de nuvem, credenciais de CI e chaves de assinatura. A resposta defensiva não é auditar pacotes manualmente: é automatizar a consulta a uma base consolidada de ameaças conhecidas e transformar o resultado em condição de merge.

Como o OSV-Scanner funciona

O OSV-Scanner, mantido pelo Google, é um scanner de vulnerabilidades escrito em Go que consulta a base pública OSV e conecta a lista de dependências de um projeto aos avisos de segurança que as afetam. A cobertura é ampla: o scanner suporta 11 ecossistemas de linguagens e 19 tipos de lockfile, incluindo npm, pip, Maven, Go modules, Cargo, Composer e NuGet, além de pacotes de sistema operacional em imagens Linux. Isso permite usar a mesma ferramenta no repositório de aplicação, no container de deploy e no artefato SBOM.

Dois recursos reduzem o ruído que costuma matar projetos de segurança em pipeline. O primeiro é a análise de chamadas: o scanner verifica se uma função vulnerável é realmente utilizada pelo projeto, em vez de reportar toda dependência que contém o código afetado, o que corta falsos positivos. O segundo é a ingestão de SBOM em formatos como CycloneDX, o que conecta o scan de dependências à política de transparência da cadeia de software sem duplicar ferramenta. Quem já avalia critérios para escolher scanner de IaC pode manter as duas frentes separadas: infraestrutura declarativa de um lado, dependências de aplicação do outro, cada uma com a ferramenta certa.

Pacotes maliciosos entram no OSV

O passo que muda o jogo para equipes defensivas é a inclusão de pacotes maliciosos na mesma base usada para vulnerabilidades. O repositório Malicious Packages da OpenSSF, documentado em guia da própria OpenSSF, publica relatos entre ecossistemas no formato OSV, cobrindo typosquatting, dependency confusion e manifest confusion. Isso significa que o mesmo scanner que procura CVE nas bibliotecas também sinaliza código declaradamente malicioso, sem segunda ferramenta nem regra customizada.

O tempo de classificação importa tanto quanto a cobertura. Segundo a OpenSSF, a maioria dos pacotes maliciosos em código aberto é classificada no OSV.dev dentro dos primeiros 3 dias de publicação. Esse dado sustenta uma defesa simples e barata: atrasar o consumo de versões novas. Configurações como um período mínimo de idade de release no gerenciador de pacotes fazem o pipeline esperar a triagem da comunidade antes de aceitar uma versão que ninguém ainda examinou. O cooldown não substitui o scan; ele fecha a janela em que o scan ainda não tem o que procurar.

Scan no pull request

A integração recomendada é a GitHub Action oficial. O comportamento é determinístico e adequado a pipeline: a Action compara um scan da branch de destino com um scan da branch de feature e falha o pull request quando a branch introduz novas vulnerabilidades ou pacotes maliciosos. O desenvolvedor recebe o sinal no momento em que está olhando para o código, não semanas depois em um relatório de compliance. O mesmo mecanismo roda em varreduras agendadas por cron para cobrir pacotes que se tornam maliciosos ou vulneráveis depois do merge, quando o repositório em si não mudou nada.

Em CI fora do GitHub, o binário CLI cobre o mesmo fluxo: varredura recursiva do diretório de origem, leitura de lockfile ou SBOM e código de saída não zero quando encontra problemas, o que qualquer sistema de integração sabe transformar em pipeline vermelho. Para quem constrói ferramentas internas, existe também o pacote Go para embutir a lógica de scan em plataformas próprias, do lado do servidor, sem depender do binário.

Checklist de implantação

Etapa Ação Prioridade
Scan por PR Adicionar a GitHub Action oficial com varredura na abertura e na atualização do pull request P1
Cooldown de versões Definir idade mínima de release no gerenciador de pacotes e fixar no arquivo de configuração do repositório P1
Varredura agendada Criar job cron semanal sobre as branches ativas para capturar avisos publicados após o merge P2
Imagens de container Apontar o scan para as imagens de deploy e revisar pacotes de sistema além das bibliotecas P2
Ingestão de SBOM Gerar CycloneDX no build e consumir no scanner para unificar inventário e alerta P2
Rota de resposta Definir quem remove, substitui e revoga credenciais quando o scan acusar pacote malicioso em produção P1

Sinais e resposta

Três sinais indicam que o pipeline está protegendo de verdade: o PR que adiciona dependência nova mostra o resultado do scan como verificação obrigatória; a varredura agendada abre ticket automático quando um pacote já presente é reclassificado como malicioso; e o histórico de build não contém resoluções de versão publicadas há menos que o cooldown definido. Se nenhum desses três existir, a implantação está incompleta.

Quando o alerta chegar, a ordem importa. Primeiro confirmar o identificador OSV do pacote e a versão afetada; depois verificar nos logs de CI quantas execuções usaram aquela versão; em seguida revogar credenciais que estavam presentes no ambiente de build durante o período de exposição, porque a suposição segura é que um pacote malicioso leu tudo que podia ler. Só então remover, substituir e reconstruir. Tratar o evento como bug de dependência, com simples atualização de versão, deixa o roubo de secrets invisível.

Fontes