Aikido

segurança da supply chain de software exige decisões, em vez de opções por defeito

Cada atualização tem o potencial de se transformar num incidente na supply chain.

Escrito por

Uma ponte permanece em serviço durante cinquenta anos com um plano de inspeção fixo, sujeita a testes de carga e mantida ao longo de todo esse período. Um motor a jato utiliza o mesmo design durante décadas sob supervisão regulatória contínua. Na maioria das disciplinas de engenharia, um design estável e comprovado, combinado com manutenção ativa, é o objetivo principal. Designs mais recentes são tratados com muito mais rigor, uma vez que nunca foram verdadeiramente testados.

Mas, por alguma razão, na engenharia de software acontece o oposto. A versão mais recente é tratada como a mais segura. E esse instinto já teve consequências graves no passado. Uma backdoor permaneceu oculta em duas versões específicas de xz-utils, versões 5.6.0 e 5.6.1, inserida por um infiltrado que passou dois a três anos a planear a obtenção de autoridade para lançar versões. Qualquer pessoa que ainda estivesse a executar a linha antiga 5.4.x nunca esteve exposta, mas quem descarregou a versão mais recente — algo que as equipas de segurança costumam ser instruídas a fazer — acabou por executar um caminho de SSH com backdoor. A própria recomendação da CISA posteriormente foi fazer o downgrade, e não o upgrade.

Já defendemos anteriormente, naquilo a que chamamos 'a armadilha da atualização', que aplicar patches no preciso momento em que surge um CVE é uma falsa economia; está a escolher entre congelar o sistema e aceitar todas as alterações que acompanham a correção. xz-utils mostra-nos o lado oposto da mesma moeda. Manter-se onde estava era a escolha segura, e a versão mais recente representava a armadilha. 

Uma forma de testar isto é perguntar a uma equipa de segurança quantos CVEs abertos possui; eles conseguirão responder rapidamente. No entanto, se perguntar porque é que um determinado pacote ou container image está a executar a versão atual, o mais provável é obter um "não sei". Simplesmente está, certo? Normalmente, baseia-se no que estava disponível quando o projeto começou, e atualizar parecia dar mais trabalho do que aquilo que valia. Indo um pouco mais além, se pedir um registo por escrito dessa decisão, é provável que receba uma resposta mais severa do género "porque haveríamos de fazer isso?". 

Então, onde é que isto falha?

Muitas vezes, os engenheiros são levados a acreditar que um container image ou pacote se torna mais arriscado à medida que o número da versão envelhece. Mas o xz-utils exemplo prova que isto não é verdade; a versão mais antiga era segura porque nada de malicioso tinha chegado até ela, e as equipas que a utilizavam não se apressaram a adotar a versão mais recente assim que foi lançada. Naturalmente, existe a hipótese de muitas equipas simplesmente não terem tido tempo para atualizar, embora quisessem fazê-lo. Ainda assim, isso é preferível a não saber que versão está a executar, nem o motivo, que é a verdadeira falha aqui.

Em vez disso, as equipas devem ponderar que, se possuem uma versão de uma biblioteca que foi testada, compreendida e é de confiança, existe um valor real em mantê-la estável. A monitorização começa no momento em que um programador, agente ou pipeline de compilação solicita um container base image ou um pacote open-source, avaliando-o antes de este entrar no ambiente. É a primeira decisão numa cadeia de decisões que são tomadas. 

Uma atualização é também uma decisão 

A determinada altura, surgirá uma nova versão, mas aplicar um patch a um CVE significa aceitar tudo o resto que foi incluído nessa mesma versão. Isso inclui dependências transitivas, alterações nos valores predefinidos e caminhos de código que ninguém na equipa chegou a ler. Na maioria das vezes, esse risco é invisível e nada corre mal. Contudo — e é um grande 'contudo' —, as coisas podem correr mal. lodash passou parte de 2026 com uma vulnerabilidade divulgada de injeção de código arbitrário que afetava todas as versões publicadas. Quando a correção foi finalmente lançada como a versão 4.18.0, falhou de imediato porque o patch substituiu uma função interna diferente que nunca tinha sido importada, fazendo com que projetos reais começassem a falhar no espaço de um dia.

A versão foi imediatamente descontinuada, com uma nota a reencaminhar os utilizadores para lodash 4.17.21 em vez disso. A alteração disruptiva não tinha qualquer relação com a vulnerabilidade em si; tratou-se de um erro de empacotamento que veio incluído juntamente com a correção de segurança. A correção real só chegou na versão 4.18.1.

Nenhuma das opções em cima da mesa era verdadeiramente segura. Atualizar para a versão 4.18.0 interrompeu as compilações de imediato. Permanecer na 4.17.21 manteve a vulnerabilidade em aberto, enquanto todas as versões anteriores à 4.18.0 continuaram vulneráveis a explorações. Algumas equipas fizeram o downgrade de volta para a 4.17.x especificamente para escapar à compilação corrompida, trocando uma compilação funcional por um caminho de injeção de código ativo, sem necessariamente perceberem que essa foi a troca que fizeram. 

Neste caso, as equipas que se encontravam numa posição mais forte foram aquelas que souberam se a sua própria aplicação sequer chamava o _ afetado.template caminho com input não fiável, e poderia avaliar essa exposição real em comparação com a alternativa avariada, em vez de avançar por defeito sem saber qual foi o verdadeiro custo.

Corrigir a vulnerabilidade sem substituir tudo o que está à volta

O backporting altera a equação. Pega na correção específica para a vulnerabilidade específica e aplica-a à versão que já está a executar, em vez de puxar tudo o resto que foi lançado em simultâneo a montante. Aplique-o a uma imagem de container e o CVE fica resolvido sem forçar uma nova imagem base. Aplique-o a um pacote e a mesma correção é feita sem um salto forçado para a versão mais recente, exatamente o salto que avariou projetos reais em execução lodash 4.18.0. Consegue resolver o problema de segurança sem alterar tudo o que está à volta. 

Um SBOM deve justificar a sua existência, não apenas existir

Um SBOM, tal como tantos documentos relacionados com conformidade, é frequentemente preenchido uma vez e arquivado. Isso indica o que estava no sistema no dia em que alguém gerou o relatório. Mas o SBOM pode fazer muito mais pela sua postura de segurança do que isso. Pode servir de linha de base de software de confiança e ajudá-lo a gerir essa linha de base de forma contínua. Para isso, teria de garantir que se mantém atualizado e que é verificado face a novas divulgações à medida que vão surgindo. Para mim, este é o sinal mais evidente de que uma organização continua a monitorizar o software que executa, em vez de se limitar a navegar à vista com o que já lá está.

Queremos que o SBOM deixe de ser apenas um inventário ou um artefacto de conformidade. Deve ser uma superfície regulada e ativamente mantida.

Então, o que precisa de mudar?

Todas estas são decisões que precisam de ser tomadas. Algumas dizem respeito a um componente de software específico num determinado momento, como avaliar um pedido, fixar a sua versão e recorrer ao backporting em vez de forçar uma atualização. Outras, como manter ou não um SBOM atualizado, estão relacionadas com os processos que tem implementados. No fundo, cada uma delas é uma decisão sobre em quê confiar. 

O mais fácil é deixar as coisas como estão, porque "funciona". Mas "funciona" não é verdade, pois não? O facto de algo funcionar não significa que vá funcionar sempre, nem que seja a forma mais segura de fazer as coisas, ou que seja a melhor forma de operar. 

Na nossa perspectiva, a abordagem mais proativa e consciente da segurança seria controlar a alteração no ponto de entrada — avaliar os pacotes antes de um programador, agente ou sistema de compilação os consumir. A partir daí, deve ter a liberdade para decidir proativamente o que entra, fixar aquilo em que confia, mantê-lo e só alterá-lo quando houver uma razão para isso.

Permanecer numa versão não deve significar continuar exposto. Aikido Libraries aplica o backport da correção à versão que já está a executar, sem atualizações forçadas, sem migrações forçadas. Comece a aplicar patches aqui.

‍

Compartilhar:

https://www.aikido.dev/blog/software-supply-chain-security-decisions-not-defaults

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