O que foi publicado entre as 09:35 e as 11:44 UTC

A primeira publicação envenenada foi o keyv na versão 6.0.0, divulgada às 09:35 UTC de 4 de agosto. A Semgrep, que deu à campanha o nome ChainDrop, contou 1.557 versões maliciosas distribuídas por 435 pacotes na vaga seguinte, entre as 09:40 e as 11:44 UTC. A Wiz, que acompanhou o mesmo incidente, chegou a mais de 400 pacotes distintos e associou-o a uma conta de mantenedor cujas credenciais tinham sido roubadas. Não eram imitações com nomes parecidos nem pacotes novos. Eram as bibliotecas verdadeiras, republicadas com o nome do mantenedor verdadeiro e com um ficheiro adicional.

Em meia hora a propagação atravessou as fronteiras entre organizações. Entre os espaços afetados contam-se @deliveroo, @ornikar, @qlik, @servicetitan, @onereach, @or-sdk, @arv-bedrock e @adminide-stack, além das próprias famílias keyv e cacheable. Essas organizações não partilham código nem proprietário. O que partilharam foi uma ficha de publicação roubada: cada infeção recolhia credenciais npm da máquina que instalava o pacote e usava-as para republicar tudo o mais que essa ficha conseguisse alcançar. É isso que faz disto um verme e não uma única publicação envenenada.

Os portadores são pacotes que ninguém escolheu

Consultámos os números de descarregamentos do registo npm para os 30 dias terminados a 3 de agosto, o dia anterior ao comprometimento. O keyv reuniu 619,7 milhões de descarregamentos. O flat-cache, 579,8 milhões. O file-entry-cache, 571,2 milhões. O cacheable-request, 137,0 milhões, o cacheable 30,1 milhões e o cache-manager 16,3 milhões. Essas seis bibliotecas somam em conjunto cerca de 1,95 mil milhões de descarregamentos no mês anterior ao envenenamento.

Quase ninguém instala o flat-cache ou o file-entry-cache deliberadamente. São auxiliares de memória intermédia que chegam por baixo das ferramentas de análise e de compilação, vários níveis abaixo numa árvore de dependências, em projetos cujos responsáveis nunca escreveram nenhum dos dois nomes. Está aí a parte incómoda da conta. Os pacotes com maior raio de ação são precisamente os que faltam na lista de dependências que reviu e aprovou, pelo que auditar as suas próprias decisões diz muito pouco sobre este incidente. O número que prevê a sua exposição é quantas vezes a sua compilação foi executada a 4 de agosto.

O código malicioso procurava o assistente de inteligência artificial

O mecanismo era um gancho preinstall, e isso importa porque é executado durante a resolução das dependências e não espera que o seu código importe nada. Os ficheiros de carregamento, setup.mjs e math_init.js, descarregavam um ambiente de execução Bun autónomo e executavam uma segunda fase ofuscada. A Wiz identificou o tráfego pelo seu agente de utilizador, Bun/1.3.13. O recolector visava fichas npm, credenciais de nuvem, chaves SSH, segredos de CI, carteiras de criptomoedas e ficheiros de configuração de ferramentas de inteligência artificial.

Escreveu também a sua persistência nos diretórios .claude e .vscode, o que é uma escolha deliberada sobre onde os programadores depositam hoje a sua confiança. Um editor e um assistente de inteligência artificial dispõem de acesso ao repositório, de permissões na linha de comandos e, cada vez mais, da autoridade para executar ordens. O comando e controlo estava escondido num contrato inteligente em Ethereum, lido com uma chamada eth_call e devolvendo o domínio npm-cache[.]com, de modo que os operadores podem redirecionar a sua infraestrutura sem distribuir código novo. A exfiltração seguiu para repositórios do GitHub criados com as identidades usurpadas e intitulados Shai-Hulud: Here We Go Again, o nome da família de código malicioso de que este descende.

Duas horas bastam para um resultado NIS2

Para um operador da União Europeia ou do Reino Unido a questão da conformidade não é apenas se foi atingido, mas se sabe descrever o que aconteceu. Dois dos espaços afetados pertencem à Deliveroo e à Ornikar, uma plataforma britânica de entregas e uma empresa francesa de escolas de condução. Nenhuma delas é uma loja desconhecida e nenhuma escolheu fazer parte deste incidente. A NIS2 coloca a segurança da cadeia de fornecimento na direção e não na equipa de segurança, e a DORA exige às entidades financeiras a mesma prova sobre o risco das tecnologias de terceiros.

O registo conta, portanto, tanto como a reparação. Determine se alguma compilação foi executada a 4 de agosto entre as 09:35 e cerca das 15:00 UTC, o momento em que o canal de comando em Ethereum foi documentado e a análise ainda prosseguia. Rode todas as credenciais que um executor pudesse alcançar, não apenas a ficha npm: chaves de nuvem, fichas do GitHub, chaves SSH e acessos de Kubernetes e Terraform. Reconstrua os executores em vez de os limpar. Depois escreva o que rodou e quando, porque é esse documento que o supervisor, o auditor ou a seguradora vão pedir. Em Portugal, o Centro Nacional de Cibersegurança é a entidade onde dá entrada um incidente de comunicação obrigatória.