Dependências
SCA com alcançabilidade: por que a maioria dos alertas de CVE é ruído
Entenda a análise de alcançabilidade em SCA, como ela filtra vulnerabilidades em código que nunca roda e como combinar com EPSS e KEV para priorizar dependências.
Neste artigo
Abra o relatório de SCA de um serviço Node.js ou Java típico e você verá dezenas, às vezes centenas, de vulnerabilidades em dependências. O time olha, não sabe por onde começar, atualiza o que é fácil e o resto fica. Seis meses depois, a lista está maior.
O problema não é o time. É que a maior parte desses alertas não representa risco real para aquela aplicação. Este artigo explica por que e como a análise de alcançabilidade resolve.
Por que tanta vulnerabilidade é irrelevante
Uma CVE numa biblioteca afeta uma função ou um conjunto de funções específicas. Mas a sua aplicação usa, em média, uma fração pequena do código de cada dependência. Pense numa biblioteca de manipulação de datas com 400 funções: a CVE está no parser de um formato de data raro que você nunca usa.
Além disso, grande parte das dependências é transitiva: você não as escolheu, elas vieram junto com outra biblioteca. Muitas existem apenas para funcionalidades que a sua aplicação nem ativa.
O SCA tradicional não sabe nada disso. Ele compara nome@versão com uma base de vulnerabilidades e alerta. Resultado: muito barulho, pouca prioridade.
O que é análise de alcançabilidade
A análise de alcançabilidade responde a uma pergunta objetiva: existe um caminho de chamadas, partindo do código da aplicação, que chegue até a função vulnerável?
Para isso, a ferramenta:
- Identifica qual função da dependência é afetada pela CVE, a partir do patch que corrigiu a falha.
- Monta o grafo de chamadas da aplicação, incluindo as dependências.
- Procura um caminho entre os pontos de entrada da aplicação e a função vulnerável.
api/rotas/relatorio.ts → gerarPdf()
→ lib-pdf.render()
→ lib-imagem.decode() ← função vulnerável (CVE)
Status: alcançável, prioridade alta
api/rotas/usuarios.ts → lib-datas.format()
(lib-datas.parseRFC2822 com CVE nunca é chamada)
Status: não alcançável, prioridade baixa
Em serviços reais, a alcançabilidade costuma descartar a grande maioria dos alertas de CVE. Na TransiTax Security, o corte chega a 92,4% em alguns ecossistemas, e todos os achados descartados continuam auditáveis.
Alcançabilidade não é a única pergunta
Alcançável é necessário, mas não suficiente. Uma boa priorização combina quatro sinais:
| Sinal | Pergunta | Fonte |
|---|---|---|
| Alcançabilidade | O meu código chama a função vulnerável? | Grafo de chamadas |
| Explorabilidade | Qual a probabilidade de essa CVE ser explorada? | EPSS, da FIRST |
| Exploração ativa | Ela já está sendo explorada no mundo real? | Catálogo KEV, da CISA |
| Exposição | O serviço afetado está acessível pela internet? | CSPM e contexto de runtime |
Uma CVE alcançável, com exploração ativa conhecida, num serviço exposto à internet, é para hoje. A mesma CVE, não alcançável, num job interno, pode esperar a próxima atualização de rotina. Esse cruzamento entre código e nuvem é o que forma os caminhos de ataque.
Limites da análise de alcançabilidade
Seja cético com qualquer promessa de 100% de precisão. Existem limites conhecidos:
- Chamadas dinâmicas. Reflexão em Java,
requirecom variável em JavaScript e importação dinâmica em Python dificultam o grafo. Boas ferramentas tratam esses casos de forma conservadora, marcando como possivelmente alcançável. - CVEs sem função identificada. Algumas vulnerabilidades afetam o pacote inteiro ou a configuração. Nesses casos, não há o que filtrar.
- Código que muda. O que não é alcançável hoje pode passar a ser amanhã. Por isso a análise precisa rodar a cada commit, e o achado precisa voltar à fila automaticamente.
Como corrigir o que sobrou
Com a fila reduzida ao que importa, o próximo gargalo é a correção. Três práticas ajudam:
- Menor versão segura. Atualizar para a última major pode quebrar a aplicação. A ferramenta deve indicar a menor versão que corrige a CVE e avisar sobre mudanças incompatíveis.
- Correção automática em PR. O AutoFix sobe a versão, roda os testes e abre o pull request com a explicação.
- Dependências sem correção. Quando o projeto foi abandonado ou a correção exige uma migração grande, bibliotecas seguras com o patch aplicado na versão atual evitam o bloqueio.
SCA vai além de CVE
Um bom SCA também cuida de:
- Pacotes maliciosos, que não têm CVE e precisam de detecção comportamental. Veja ataques à cadeia de suprimentos.
- Licenças, para evitar surpresas com GPL e AGPL. Veja licenças de código aberto.
- SBOM, o inventário formal que clientes e reguladores começam a exigir. Veja o guia de SBOM.
- Saúde do projeto, como pacotes sem manutenção há anos.
Quer ver isso rodando no seu código?
Em 30 minutos mostramos a TransiTax Security num repositório seu, separando o que é explorável do que é ruído.
Falar com um especialistaEscrito por
Equipe de Pesquisa TransiTax Security
Engenheiros de segurança de aplicações e de nuvem que acompanham registros de pacotes, bases de vulnerabilidades e técnicas de ataque. Conheça a equipe.
Perguntas frequentes
Respostas diretas às dúvidas mais comuns sobre o tema.
O que é alcançabilidade em SCA?
É a verificação de que o código da aplicação chama, direta ou indiretamente, a função vulnerável de uma dependência. Sem esse caminho, a vulnerabilidade existe no pacote, mas não é explorável naquela aplicação.
Vulnerabilidade não alcançável pode ser ignorada?
Pode ser despriorizada, não esquecida. Ela deve ser corrigida na próxima atualização de rotina e voltar à fila automaticamente se o código mudar e passar a chamar a função afetada.
O que é EPSS?
O Exploit Prediction Scoring System, mantido pela FIRST, estima a probabilidade de uma CVE ser explorada nos próximos 30 dias, com base em dados reais de ataques.
O que é o catálogo KEV?
É o catálogo de vulnerabilidades conhecidamente exploradas mantido pela CISA, agência de cibersegurança dos Estados Unidos. Uma CVE no KEV já foi usada em ataques reais.
A análise de alcançabilidade funciona em todas as linguagens?
A precisão varia por linguagem. É mais madura em Java, JavaScript, TypeScript, Python e Go, e mais limitada em linguagens muito dinâmicas ou com muita geração de código em tempo de execução.