Na madrugada de 4 de agosto, uma das maiores cadeias de dependência do ecossistema JavaScript virou arma. A conta GitHub do mantenedor do keyv — um dos pacotes mais baixados da npm, com cerca de 127 milhões de downloads por semana — foi comprometida. Horas depois, versões envenenadas não só do keyv, mas de dezenas de pacotes de cache vizinhos, começaram a ser publicadas no registro.
O resultado é o que pesquisadores batizaram de "Mini Shai-Hulud": um worm de roubo de credenciais que se replica ao reutilizar o próprio ecossistema como vetor de propagação. A estimativa inicial de 444 pacotes afetados subiu para mais de 860 pacotes e cerca de 2 bilhões de instalações acumuladas em menos de 48 horas.
O que torna este ataque particularmente sofisticado é o detalhe da proveniência npm: as versões maliciosas foram publicadas com proveniência válida assinada pelo GitHub Actions da conta comprometida — o selo que deveria provar que o código veio do repositório legítimo e de um build auditável.
O Que Foi Comprometido
O alvo foi um conjunto de pacotes de cache extremamente populares, todos interconectados pelo mesmo mantenedor ou pela família de bibliotecas cacheable. Os mais impactados:
| Pacote | Versão afetada | Downloads estimados |
|---|---|---|
| keyv | 6.0.0 | ~604 milhões/mês |
| flat-cache | 6.1.24 | ~580 milhões/mês |
| file-entry-cache | 11.1.6 | ~571 milhões/mês |
| cacheable-request | 13.0.20 | ~137 milhões/mês |
| cacheable | 2.5.1 | ~30 milhões/mês |
| cache-manager | 7.2.10 | Alto (framework de cache) |
| @cacheable/* (memory, node-cache, utils, net) | Múltiplas | Alto (família cacheable) |
| ecto | 5.0.1 | Moderado |
O keyv é dependência indireta de milhares de projetos via bibliotecas de cache populares
O alcance é ampliado porque o keyv é uma dependência transitiva: projetos não precisam instalá-lo diretamente. Frameworks de build, ferramentas de lint, loaders de bundlers e bibliotecas de requisição HTTP o puxam silenciosamente em cascata. Uma única dependência envenenada no topo contamina toda a árvore.
Como o Worm Funciona
O "Mini Shai-Hulud" é um credential-stealer distribuído como worm. O nome brinca com os vermes de areia de Duna — e não por acaso: o código malicioso navega pela areia do ecossistema, infectando máquinas de desenvolvedores e CI, coletando credenciais e tentando se propagar adiante.
O payload foi projetado para atacar um dos pontos mais confiáveis do ambiente do desenvolvedor: as variáveis de ambiente e os arquivos de configuração de credenciais. Ao rodar durante a instalação de qualquer pacote que dependa do keyv, o worm:
- Escaneia arquivos como .env, ~/.npmrc, ~/.ssh e tokens de provedores de nuvem
- Captura credenciais de registros privados, chaves de API e chaves SSH
- Exfiltra os dados para um servidor de comando controlado pelo atacante
- Tenta usar tokens npm roubados para publicar novas versões maliciosas de pacotes populares — transformando a vítima em vetor do próximo salto
Essa última etapa é o que caracteriza um worm de verdade: ele não apenas rouba, mas se recicla. Com um token npm válido em mãos, o código pode executar npm publish como a vítima, repetindo o ciclo de contaminação em escala.
A Ironia da Proveniência Assinada
Em 2021, a npm introduziu o SLSA provenance: quando um pacote é publicado de dentro de um workflow do GitHub Actions, o registro registra um build provenance criptograficamente assinado que vincula a publicação ao repositório e ao commit de origem. É o mecanismo que deveria permitir distinguir uma publicação legítima de uma feita por um atacante com credenciais roubadas.
O problema
As versões maliciosas chegaram ao registro com proveniência válida, assinada pelo GitHub Actions. Do ponto de vista do registro, pareciam builds legítimos do próprio projeto. A garantia de proveniência protege a origem do repositório — mas não a autenticidade do mantenedor que controla a conta.
Pesquisadores apontam a lição: proveniência assina o repositório e o pipeline, não a pessoa ou a intenção. Quando a conta do mantenedor é tomada, o atacante herda toda a cadeia de confiança — incluindo o selo que deveria transmitir segurança.
Proveniência assinada não protege contra contas comprometidas — é preciso verificar o histórico e a identidade do publicador
Cronologia do Incidente
O ataque seguiu um roteiro rápido e coordenado:
- 4 de agosto: a conta GitHub do mantenedor é comprometida; versões envenenadas de keyv, flat-cache, file-entry-cache e da família cacheable são publicadas em cascata
- 4 de agosto (tarde): pesquisadores independentes detectam o comportamento atípico e alertam a comunidade; a npm inicia a remoção das versões
- 5 de agosto: o escopo revelado sobe para 444 pacotes afetados direta ou indiretamente
- 6 de agosto: estimativas da comunidade apontam para mais de 860 pacotes e um impacto acumulado em cerca de 2 bilhões de instalações
O número de pacotes afetados não significa que todos foram publicados com payload — muitos entraram na lista por compartilhar o mesmo mantenedor ou por depender transitivamente de versões comprometidas, exigindo análise caso a caso.
O Que Você Deve Fazer Agora
Se o seu projeto usa qualquer pacote de cache popular, o caminho de mitigação é direto:
- Atualize imediatamente keyv, flat-cache, file-entry-cache, cacheable-request, cacheable, cache-manager, @cacheable/* e ecto para versões corrigidas
- Rode
npm audite revise a árvore de dependências procurando versões listadas nas advisories oficiais - Roteie credenciais: rotacione tokens npm, chaves SSH, tokens de CI e variáveis de ambiente que possam ter sido expostas
- Inspecione o lockfile para confirmar que nenhuma versão afetada permanece como dependência transitiva
- Revise pipelines de CI — um worm desse tipo costuma persistir exatamente onde a automação roda sem supervisão
Lições para a Indústria
O "Mini Shai-Hulud" reforça um padrão que se repete: os pacotes mais baixados são os menos auditados. Bibliotecas de infraestrutura como cache são usadas em escala astronômica, mas raramente recebem o mesmo escrutínio que frameworks com forte visibilidade.
A comunidade aponta medidas estruturais que vão além da correção pontual:
- Revisão humana obrigatória para publicação de novas versões de pacotes críticos, mesmo para mantenedores legítimos
- 2FA obrigatória — e, onde for possível, chaves hardware-backed — para contas de mantenedores de pacotes de alto tráfego
- Quarentena temporal de novas versões de pacotes amplamente usados, para permitir inspeção antes da adoção em massa
- Ambientes de CI descartáveis com credenciais efêmeras, reduzindo o valor de um token roubado
- Registros privados com políticas de publicação que não confiem cegamente na proveniência GitHub Actions
Para as empresas, a recomendação prática é tratar dependências de cache como componentes de infraestrutura crítica: pinagem rigorosa, verificação de integridade, review de lockfiles e monitoramento de publicações novas em pacotes da árvore de dependências.
A saga ainda está em andamento, e o escopo final só será conhecido quando a análise das versões removidas terminar. Mas a direção já está clara: ataques de supply chain evoluíram de "commit malicioso acidental" para operações coordenadas que abusam dos mecanismos de confiança do próprio ecossistema. Quem proteger as credenciais e o pipeline primeiro, sai na frente.
Sobre o Blog Wirebird
O Blog Wirebird é uma fonte confiável de conteúdo técnico sobre Inteligência Artificial, Cloud Computing, DevOps e transformação digital.