
Scanner para o ataque à cadeia de suprimentos keyv/cacheable: detecta pacotes npm comprometidos, verifica hashes de payload e encontra implantes de persistência nos modos repo e host.
English | Português
Scanner standalone para o incidente de supply chain keyv/cacheable ("Shai-Hulud: Here We Go Again", 04/ago/2026) — 440+ pacotes npm comprometidos por um worm auto-propagante que rouba credenciais de cloud/CI e planta persistência com dead-man's switch.
O output do scanner é em inglês (findings, ações, relatório HTML). Esta página traduz o contexto e o passo a passo para o público brasileiro; os comandos são idênticos aos da versão em inglês.
Detecta, em minutos e sem instalar nada:
package-lock.json, npm-shrinkwrap.json, yarn.lock (v1 e Berry), pnpm-lock.yaml e bun.lock — incluindo dependências transitivas, com a cadeia completa (ex.: eslint → file-entry-cache → flat-cache → [email protected]);node_modules (nome + hash SHA-256 dos artefatos conhecidos);SUSPECT, nunca confirmadas sem hash;.claude/settings.json e .vscode/tasks.json, artefatos temporários (bun-dl-*);keyv/cacheable foi comprometida; o atacante publicou versões novas com um gancho "preinstall": "node setup.mjs" — código que roda antes de o pacote ser instalado, com os privilégios de quem rodou npm install.setup.mjs baixa o runtime Bun do GitHub e executa o payload nele — evasão contra ferramentas que só monitoram processos node.Math_Symbol.js (~728 KB, ofuscado) rouba credenciais: metadados de instância AWS, chaves AWS/GCP/Azure, tokens Vault, service accounts de Kubernetes, secrets de GitHub Actions, tokens npm, e faz varredura genérica por regex atrás de chaves privadas e bearer tokens em disco.npm install/npm ci com lifecycle scripts habilitados desde 04/08/2026 09:35 UTC. Com --ignore-scripts, o gancho não executou..claude/settings.json (SessionStart) e .vscode/tasks.json (folderOpen) que executam o loader ao abrir a pasta clonada — sem npm install, sem instalar nada. Isso inclui quem clonou o repositório para investigar o incidente e agentes de codificação com IA que abriram o diretório — um dos primeiros casos públicos de hooks de agente de IA (.claude/) usados como vetor de supply chain.O implante instala um "vigia" (gh-token-monitor) mantido vivo por LaunchAgent (macOS) ou serviço systemd de usuário + loginctl enable-linger (Linux). A cada 60 segundos ele valida o token GitHub roubado contra a API. Enquanto o token funciona, nada acontece. Quando a resposta vira 4xx — ou seja, no instante em que você revoga o token — ele executa via eval o conteúdo de ~/.config/gh-token-monitor/handler: um comando arbitrário definido remotamente pelo atacante. A análise pública não sabe o que ele contém — pode ser destruição de dados, reimplante, ransomware ou nada. O risco não é avaliável; por isso a ordem de resposta é absoluta.
Três propriedades que mudam a resposta:
host.[email protected] saiu com atestação SLSA passando. Provenance atesta integridade de build, não de fonte: o workflow legítimo compilou código já trojanizado.package.json (o gancho preinstall) e em dois arquivos novos adicionados ao pacote (setup.mjs, Math_Symbol.js).eslint → file-entry-cache → flat-cache → keyv. Por isso o scanner mostra a cadeia em cada achado.O scan.mjs tem as seguintes características — importantes para quem está respondendo a um incidente de supply chain:
npm install. Audite scan.mjs inteiro em 15 minutos antes de rodar.--update (baixar manifesto de IOCs novo), explícita e opcional.docker run --network=none ou máquina isolada: basta copiar scan.mjs + iocs.json.Requisito: Node.js ≥ 18 (qualquer máquina com npm já tem). Baixe os dois arquivos — scan.mjs + iocs.json — e pronto: não há instalação.
Heads-up: se você clonou este repositório inteiro, a pasta
fixtures/contém IOCs inertes usados nos testes (nomes e versões reais, conteúdo dummy — não há malware). O scanner a ignora automaticamente e avisa no output; achados vindos dela só aparecem se você a escanear de propósito.
Há dois modos de execução que respondem perguntas diferentes e é isso que define onde rodar:
repo lê lockfiles e node_modules — e lockfiles estão no git, então pode ser centralizado: uma pessoa varre todos os repositórios da empresa.host procura o implante (watcher, LaunchAgent/systemd, hooks de IDE), que mora na máquina onde o código executou — isso não está no git e não dá para centralizar.node scan.mjs repo /pasta/com/todos/os/repositorios --json=resultado.json --html=relatorio.html
Responde "quais projetos estão expostos" em minutos, sem envolver ninguém. Aceita vários caminhos; varre subdiretórios (monorepos e workspaces inclusos).
Para cada projeto com achado, identifique quem mexeu nele desde 04/08 09:35 UTC (git log, logs de CI). Essas pessoas rodam, na máquina delas:
node scan.mjs # diretório atual + host, em ~30 segundos
Está no escopo quem: (a) rodou npm install/npm ci na janela; ou (b) apenas clonou e abriu a pasta no VS Code ou num agente de IA — o vetor B dispensa instalação.