Aikido

A armadilha do upgrade: quando o upgrade é a resposta errada para uma CVE

Escrito por
Sooraj Shah

O conselho é sempre o mesmo quando uma ferramenta de vulnerabilidade sinaliza uma CVE: faça upgrade. Mova para a versão corrigida para que você possa fechar o ticket e seguir em frente. Tornou-se um reflexo tão automático que ninguém para para perguntar se realmente funcionará.

A correção proposta falha de três maneiras específicas. Não há versão para fazer upgrade e nunca haverá, a versão corrigida ainda não foi lançada, ou a correção é lançada e quebra seu aplicativo. 

Em resumo, as melhores práticas e todos os frameworks, de SOC2 a ISO27001, dizem para manter suas dependências atualizadas. Mas fazer upgrade não equivale a corrigir, e, no entanto, é a única resposta que muitas ferramentas oferecem. 

Nem sempre foi um instinto errado. Os mantenedores (felizmente) têm corrigido vulnerabilidades na versão mais recente, e por anos isso foi suficiente.

CVEs são reportadas > mantenedores as corrigem > você faz upgrade > você obtém a correção.

Mas os mantenedores geralmente não voltam para corrigir versões mais antigas. Assim, as equipes foram condicionadas a sempre fazer upgrade para a versão mais recente quando podiam, e os atacantes notaram esse padrão e aprenderam a explorá-lo. Agora, você faz upgrade para ter a CVE corrigida, há alguma chance de que em algum lugar na atualização haja malware, então baixar a versão mais recente não é mais automaticamente seguro.  

No início deste ano, atacantes comprometeram uma conta de mantenedor responsável por alguns dos pacotes mais baixados no npm. chalk e debug, somando mais de dois bilhões de downloads por semana. Eles publicaram versões maliciosas através do canal oficial, e todo pipeline configurado para auto-atualização os puxou diretamente. Equipes seguindo as melhores práticas estavam distribuindo malware em minutos. 

É uma situação sem saída. Você se mantém atualizado e corre o risco de baixar malware, ou você congela e acumula dívida de segurança. Isso é o que chamamos de armadilha do upgrade. A versão que você executa e as correções de segurança aplicadas a ela não precisam ser a mesma decisão.

As três maneiras pelas quais o upgrade falha

É claro que o “upgrade” funciona muitas vezes e ainda é importante. Mas há três situações em que ele falha. 

A primeira é quando não há uma versão corrigida para a qual migrar (e nunca haverá). Considere request, um dos clientes HTTP mais usados no Node, que foi descontinuado desde 2020. E, no entanto, ele ainda aparece em todos os lugares, geralmente arrastado por algum pacote pai que ninguém mexeu há anos. Quando você executa uma ferramenta SCA sobre o request, a ferramenta encontra uma CVE para bypass de mitigação de server-side request forgery (SSRF). Adivinhe qual é a correção aqui, de acordo com a ferramenta SCA? Sim, fazer upgrade.

Mas o problema é que não há nada para fazer upgrade, e nunca haverá. request não é mantido há anos. O aviso praticamente diz isso, observando que a falha afeta apenas as versões que o mantenedor não oferece mais suporte (ou seja, todas as versões). Então, neste caso, “upgrade” na verdade significa remover request e migrar para algo como axios ou node-fetch. Isso é uma reescrita e uma migração, e significa que, até que alguém tenha tempo para isso, a CVE simplesmente fica lá. 

Isso pressupõe que a correção deve vir do mantenedor. Para pacotes EOL, alguém ainda precisa entender a vulnerabilidade e escrever uma correção para a versão já em uso. As distros fazem isso para pacotes de nível de SO há anos. A mesma abordagem agora existe para bibliotecas de aplicativos, que é onde a maioria das equipes está presa.

O segundo tipo de upgrade é quando a correção não existe ainda mesmo que o pacote esteja ativo. A biblioteca popular lodash passou um período de tempo no ano passado com duas vulnerabilidades divulgadas afetando todas as versões publicadas até e incluindo 4.17.23. Como essa era a versão mais recente, não havia nada para fazer upgrade. npm audit sinalizou as CVEs e relatou que não havia correção disponível. Assim, embora o conselho de fazer upgrade fosse válido, não era realmente viável porque a versão corrigida não havia sido lançada.

O terceiro é quando a correção é lançada e quebra sua aplicação. CVE-2026-48937 no Node é um exemplo recente. A correção para a vulnerabilidade veio junto com uma SEMVER-MAJOR atualização para a nghttp2 dependência e a remoção do suporte a sinalização de prioridade HTTP/2. O comportamento vulnerável e o recurso sendo removido faziam parte do mesmo código subjacente, então não havia como aplicar a correção de segurança sem também aplicar a mudança disruptiva. Os usuários tiveram que procurar por setPriority e .priority() e removê-los antes que pudessem fazer qualquer upgrade. 

Este é o risco de qualquer upgrade. Um novo lançamento pode mudar o comportamento de um pacote o suficiente para quebrar algo que estava funcionando, forçar outras dependências a fazerem upgrade junto, ou chegar como uma versão principal que exige uma migração antes mesmo de ser instalada. 

E indo um passo além, se você atualiza um pacote, pode ter que atualizar outros cinco. Um deles pode quebrar algo que seu sistema depende. A engenharia então tem a escolha entre um item do roadmap que gera receita e o upgrade. Adivinhe qual vence 😬. Você acaba com dívida técnica e um acúmulo de CVEs. 

Como a IA mudou o cenário

A maioria das empresas tem um backlog de CVEs grande demais para ser resolvido, e estão apreensivas porque os modelos de fronteira mais recentes podem encontrar vulnerabilidades mais rapidamente. Mas o que é mais ameaçador é que eles podem encadear CVEs de média gravidade de uma forma que os transforma em um padrão de exploração crítico. O modelo atual de varredura, triagem e tentativa de distribuir esse trabalho para os engenheiros não escala rápido o suficiente para gerenciar esse problema. A IA está efetivamente agravando um problema existente e tornando mais urgente para as organizações corrigi-lo.

O que a indústria faz a respeito

A atualização era a única resposta realista por muito tempo. Os backlogs de CVE e as builds quebradas que se seguiram foram uma consequência previsível do conjunto limitado de escolhas. Existem, em geral, três abordagens para este problema. Duas delas trocam um problema por outro. A terceira se aproxima mais de realmente fechar o CVE sem criar um novo.

A primeira é a triagem no ponto de consumo. Antes que um pacote chegue à sua build, ele é verificado: esta dependência é segura para instalar? É uma camada necessária, especialmente após ataques como chalk e debug. Mas não se aplica a pacotes vulneráveis já em produção. É um portão de entrada em vez de uma correção e, fora desse escopo, a resposta continua sendo a atualização.  

A segunda opção passa por migrar as equipas para uma stack de substituição blindada. Em vez de corrigirem o que já utilizam, são empurradas para um ecossistema proprietário que não controlam. Pode funcionar para aplicações greenfield, mas para sistemas em produção vinculados a bibliotecas específicas e imagens base, transforma a remediação num projeto de migração. Uma vez lá dentro, sair é um projeto por si só.

A terceira opção consiste em aplicar a correção (backporting) à versão já em utilização. A maioria das organizações não tem capacidade, conhecimentos especializados nem disposição para o fazer. Quando um CVE é corrigido amontante (upstream), a parcela mais restrita de código que resolve o problema é isolada da versão mais recente e aplicada de forma limpa à versão mais antiga que já está a executar. Validar que mais nada foi alterado exige verdadeira competência técnica e manutenção contínua. As distribuições fazem versões disto há anos. Fazê-lo em bibliotecas de aplicações, de forma automática, ao ritmo a que surgem os CVEs, é um problema completamente diferente. Para pacotes em fim de vida (EOL) onde não existe correção amontante, alguém continua a ter de compreender a vulnerabilidade e escrever uma correção para a versão já em utilização. Esse mesmo trabalho existe agora como uma opção escalável para bibliotecas de aplicações, que é onde a maioria das equipas se depara com obstáculos. O único caso em que isto não se aplica é quando ainda não existe nenhuma correção amontante. Se o mantenedor não escreveu o patch, não há nada para isolar e aplicar. O CVE permanece lá até que alguém o faça.

Você mantém a versão em que seu aplicativo já confia, aplica apenas a correção, e não acumula CVEs contra uma versão congelada nem puxa a versão mais recente e tudo o que vem com ela.

Pense na sua stack de software como uma casa em que você mora há anos. A maioria das ferramentas ou monitora o que entra, ou entrega uma lista de reparos e diz para você resolver, ou pede para você se mudar para uma casa nova e menor que elas construíram. Consertar a casa em que você já mora é o que a maioria das equipes realmente quer.

Agora existe uma opção que faz exatamente isso: corrigir vulnerabilidades nos pacotes de código aberto dos quais sua aplicação depende, sem a necessidade de upgrade, com Aikido Libraries.

‍

Compartilhar:

https://www.aikido.dev/blog/cve-upgrade-breaking-changes-open-source

Assine para receber notícias

4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes

Torne-se seguro hoje,
de forma rápida e gratuita.

Proteja o seu código, a cloud e o runtime num sistema central.
Conecte um repositório para descobrir o que os agentes de raciocínio encontram na sua base de código.

Não é necessário cartão de crédito | Resultados do teste em 32 segundos.
Confiado por mais de 150 mil orgs