Aikido

A armadilha da atualização: quando a atualização é a resposta errada a um CVE

Escrito por
Sooraj Shah

O conselho é sempre o mesmo quando uma ferramenta de deteção de vulnerabilidades identifica um CVE: atualizar. Mudar para a versão corrigida para que se possa encerrar o ticket e seguir em frente. Tornou-se um reflexo tão automático que ninguém se detém para perguntar se isso vai realmente funcionar.

A correção proposta falha de três formas específicas. Não existe uma versão para a qual se possa atualizar e nunca existirá, a versão corrigida ainda não foi lançada, ou a correção é lançada e causa falhas na sua aplicação. 

Resumindo, as melhores práticas e todas as normas, desde a SOC2 até à ISO 27001, recomendam que se mantenham as dependências atualizadas. No entanto, atualizar não é o mesmo que corrigir, e, ainda assim, é a única solução que muitas ferramentas oferecem. 

Nem sempre foi um instinto errado. Os responsáveis pela manutenção (felizmente) têm vindo a corrigir vulnerabilidades na versão mais recente e, durante anos, isso foi suficiente.

As CVEs são comunicadas > os responsáveis pela manutenção aplicam as correções > atualizas > obténs a correção.

Mas os responsáveis pela manutenção não costumam voltar atrás para corrigir versões mais antigas. Assim, as equipas habituaram-se a atualizar sempre para a versão mais recente sempre que possível, e os atacantes repararam nesse padrão e aprenderam a explorá-lo. Agora, quando atualiza para corrigir o CVE, existe alguma probabilidade de que, algures na atualização, haja malware; por isso, obter a versão mais recente já não é automaticamente seguro.  

No início deste ano, os atacantes comprometeram uma conta de mantenedor responsável por alguns dos pacotes mais descarregados no npm: o chalk e o debug, que, juntos, somam mais de dois mil milhões de descargas por semana. Publicaram versões maliciosas através do canal oficial e todos os pipelines configurados para atualização automática descarregaram-nas imediatamente. Equipas que seguiam as melhores práticas acabaram por distribuir malware em poucos minutos. 

É uma situação em que todos saem a perder. Ou mantém-se atualizado e corre o risco de instalar malware, ou fica estagnado e acumula uma dívida de segurança. É a isto que chamamos a «armadilha da atualização». A versão que utiliza e as correções de segurança que lhe são aplicadas não têm de ser a mesma decisão.

As três formas pelas quais a atualização pode falhar

É claro que a «atualização» funciona na maioria das vezes e continua a ser importante. Mas há três situações em que não resulta. 

O primeiro caso é quando não existe uma versão fixa para a qual se possa migrar (e nunca existirá). Por exemplo, pedido, um dos clientes HTTP mais utilizados no Node, que está obsoleto desde 2020. No entanto, continua a aparecer em todo o lado, normalmente trazido por algum pacote pai que ninguém toca há uma eternidade. Quando se executa uma SCA no `request`, a ferramenta identifica um CVE relacionado com a contornagem da mitigação da falsificação de pedidos do lado do servidor (SSRF). Adivinha qual é a solução sugerida pela SCA ? Pois é, atualizar.

Mas o problema é que não há nada para que se possa atualizar, e nunca haverá. pedido não é mantido há anos. O aviso praticamente confirma isso, referindo que a falha afeta apenas as versões que o responsável pela manutenção já não suporta (ou seja, todas as versões). Assim, neste caso, «atualizar» significa, na verdade, desinstalar pedido sair e passar para algo como axios ou node-fetch. Trata-se de uma reescrita e de uma migração, o que significa que, até que alguém tenha tempo para o fazer, o CVE fica simplesmente parado. 

O segundo tipo de atualização ocorre quando a correção não existe no entanto mesmo que o pacote esteja ativo. A biblioteca popular lodash No ano passado, houve um período em que existiam duas vulnerabilidades divulgadas que afetavam todas as versões publicadas até à 4.17.23, inclusive. Como essa era a versão mais recente, não havia para onde atualizar. npm audit assinalou as CVEs e informou que não havia nenhuma correção disponível. Assim, embora a recomendação para atualizar fosse válida, na prática não era viável, uma vez que a versão corrigida ainda não tinha sido lançada.

A terceira situação é quando a correção é lançada e provoca falhas na sua aplicação. CVE-2026-48937 no Node é um exemplo recente. A correção para a vulnerabilidade veio incluída numa SEMVER-MAJOR atualização do nghttp2 dependência e a remoção do suporte à sinalização de prioridade HTTP/2. O comportamento vulnerável e a funcionalidade que estava a ser removida faziam parte do mesmo código subjacente, pelo que não havia forma de aplicar a correção de segurança sem, ao mesmo tempo, aplicar a alteração que causava incompatibilidade. Os utilizadores tiveram de procurar com o grep por definirPrioridade e .priority() e eliminá-los antes mesmo de terem oportunidade de evoluir. 

Este é o risco inerente a qualquer atualização. Uma nova versão pode alterar o comportamento de um pacote de tal forma que provoque falhas no que antes funcionava, obrigue outras dependências a serem atualizadas em simultâneo ou seja lançada como uma versão principal que exija uma migração antes mesmo de poder ser instalada. 

E, para ir um pouco mais longe, se atualizares um pacote, podes ter de atualizar outros cinco. Um desses pode causar falhas em algo de que o teu sistema depende. A equipa de engenharia tem então de escolher entre um item do plano de desenvolvimento que gera receitas e a atualização. Adivinha qual deles ganha 😬. Acabas então por ficar com dívida técnica e uma pilha de CVEs a acumular-se. 

Como a IA alterou o panorama

A maioria das empresas tem uma lista de CVEs pendentes demasiado grande para ser processada e está preocupada porque os modelos de detecção de vulnerabilidades mais recentes conseguem identificar vulnerabilidades mais rapidamente. Mas o que constitui uma ameaça ainda maior é o facto de poderem encadear CVEs de gravidade média de forma a transformá-las num padrão de exploração crítico. O modelo atual de análise, triagem e distribuição desse trabalho aos engenheiros não se adapta com rapidez suficiente para gerir este problema. A IA está, efetivamente, a agravar um problema já existente e a tornar a sua resolução ainda mais urgente para as organizações.

O que o setor faz a esse respeito

Durante muito tempo, a atualização foi a única solução realista. Os atrasos na resolução dos CVE e as compilações com erros que se seguiram foram uma consequência previsível do conjunto limitado de opções. Existem, em termos gerais, três abordagens para este problema. Duas delas trocam um problema por outro. A terceira resolve efetivamente o CVE sem correr o risco de criar um novo.

A primeira é a verificação no ponto de consumo. Antes de um pacote chegar à vossa compilação, é verificado: será que esta dependência é segura para instalar? Trata-se de uma camada necessária, especialmente após ataques como o «chalk» e o «debug». No entanto, não se aplica a pacotes vulneráveis que já se encontrem em produção. É mais um filtro do que uma correção e, fora desse âmbito, a solução continua a ser a atualização.  

A segunda opção consiste em migrar as equipas para uma pilha de substituição reforçada. Em vez de corrigir o que as equipas já utilizam, estas são forçadas a aderir ao ecossistema proprietário de terceiros. Isto pode funcionar para aplicações criadas de raiz, mas, no caso de sistemas de produção ligados a bibliotecas e imagens de base específicas, transforma a correção num projeto de migração. Uma vez lá dentro, sair torna-se um projeto à parte.

A terceira opção consiste em aplicar a correção retroativamente à versão já em uso. A maioria das organizações não tem a capacidade, os conhecimentos especializados nem a vontade para o fazer. Quando um CVE é corrigido na fonte, a parte mais reduzida de código que o corrige é isolada da versão mais recente e aplicada de forma limpa à versão mais antiga que já está a utilizar. Validar que nada mais mudou requer verdadeira especialização e manutenção contínua. As distribuições têm vindo a fazer versões disto há anos. Fazer o mesmo em bibliotecas de aplicações, automaticamente, ao ritmo a que os CVEs surgem, é um problema completamente diferente. Esta abordagem significa que mantém a versão em que a sua aplicação já confia, aplica apenas a correção e, assim, não acumula CVEs numa versão congelada nem obtém a versão mais recente com tudo o que ela traz consigo. 

Pense na sua pilha de software como uma casa onde vive há anos. A maioria das ferramentas ou filtra o que entra pela porta, entrega-lhe uma lista de reparações e diz-lhe para tratar disso, ou pede-lhe para se mudar para uma casa nova e mais pequena que construíram. O que a maioria das equipas realmente quer é reparar a casa onde já vive.

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

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

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.