
Verificador de IOC para o ataque à cadeia de suprimentos npm TanStack/Mini Shai-Hulud (CVE-2026-45321)
curl -fsSL https://raw.githubusercontent.com/nkopylov/tanscript-exploit-check/main/check-tanstack-exploit.sh | bash
Ou clone e execute localmente:
git clone https://github.com/nkopylov/tanscript-exploit-check.git
cd tanscript-exploit-check
./check-tanstack-exploit.sh [project_dir ...]
Este verificador cobre duas ondas da campanha de ataque à cadeia de suprimentos Mini Shai-Hulud pela TeamPCP:
Em 11 de maio de 2026 (19:20-19:26 UTC), um atacante publicou 84 versões maliciosas em 42 pacotes npm @tanstack/* em uma janela de 6 minutos. O ataque também atingiu pacotes da Mistral AI, UiPath, OpenSearch e outros — mais de 170 pacotes no total entre npm e PyPI.
Nenhuma credencial de mantenedor foi roubada. O atacante explorou a própria cadeia de confiança do CI/CD por meio de um ataque em 3 estágios:
pull_request_target — Um fork descartável do GitHub abriu um PR que executou código do atacante no contexto de segurança do repositório baseEm 19 de maio de 2026 (01:39-02:06 UTC), a conta npm comprometida atool ([email protected]) publicou 637 versões maliciosas em 314 pacotes em duas ondas automatizadas. Alvos de alto impacto incluem:
size-sensor (4.2M downloads/mês)echarts-for-react (3.8M downloads/mês)@antv/scale (2.2M downloads/mês)timeago.js (1.15M downloads/mês)Esta onda usou um payload baseado em Bun (index.js de 498KB) acionado via "preinstall": "bun run index.js", com um payload de segundo estágio oculto em commits impostores enviados para o repositório GitHub antvis/G2 através da exploração de compartilhamento de objeto fork.
Ambas as ondas usam a mesma família de ferramentas "Mini Shai-Hulud":
gh-token-monitor (Onda 1) e kitty-monitor (Onda 2) via LaunchAgent/systemd; hooks em .claude/settings.json e .vscode/tasks.jsontoJSON(secrets), troca de token OIDC npmrm -rf ~/ se o token do GitHub for revogado enquanto o daemon estiver ativofiredalazer, comandos assinados com RSA-PSSApenas @tanstack/router* e @tanstack/start* foram afetados. NÃO afetados: @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store.
Veja o aviso completo para todos os 42 pacotes.
Todos os pacotes publicados pelo usuário npm atool ([email protected]) receberam versões maliciosas em 19 de maio de 2026. Pacotes de alto impacto incluem:
| Pacote | Downloads mensais |
|---|---|
size-sensor | 4.2M |
echarts-for-react | 3.8M |
@antv/scale | 2.2M |
Além de 310+ pacotes principalmente no escopo @antv/* (@antv/g2, @antv/g6, @antv/l7, @antv/s2, @antv/x6, @antv/f2, etc.), ai-figure, timeago-react, jest-canvas-mock, jest-date-mock e outros.
Veja o artigo do SafeDep para a lista completa.
CRÍTICO: Desative a chave de homem morto ANTES de revogar qualquer token. O malware limpa
$HOMEse os tokens forem revogados enquanto o daemon estiver ativo.
gh-token-monitor E kitty-monitor) e remova os serviços LaunchAgent/systemd.claude/router_runtime.js, .vscode/setup.mjs, ~/.local/share/kitty/cat.py, /var/tmp/.gh_update_state, etc.)node_modules e lockfiles, reinstale com --ignore-scriptsapi.masscan.cloud, filev2.getsession.org, git-tanstack.com, t.m-kosche.com)Copie e cole estes prompts em seu agente de codificação de IA (Claude Code, Cursor, Cline/OpenClaw, Windsurf, Hermes, etc.) para endurecer seu projeto contra ataques à cadeia de suprimentos como este.
Endureça a configuração npm deste projeto contra ataques à cadeia de suprimentos. Faça o seguinte:
Fixar versões exatas: Remova todos os prefixos
^e~de cada dependência empackage.jsonpara quenpm installnunca puxe silenciosamente uma versão recém-publicada.Desabilitar scripts postinstall por padrão: Adicione
ignore-scripts=trueao.npmrc. Em seguida, adicione um script"preinstall"explícito empackage.jsonque execute apenas os scripts de ciclo de vida conhecidos como seguros que este projeto realmente precisa (se houver).Impor instalações apenas com lockfile no CI: Certifique-se de que o CI use
npm ci(nãonpm install). Se houver um arquivo de configuração do CI, verifique isso. Caso contrário, anote como uma etapa manual.Adicionar verificação de proveniência: Adicione
npm audit signaturescomo uma etapa no pipeline do CI e como um hook git pre-push.
Audite e endureça a configuração do agente de codificação de IA deste projeto contra ataques de injeção na cadeia de suprimentos (como a campanha TanStack/Mini Shai-Hulud que injetou hooks maliciosos em
.claude/settings.jsone.vscode/tasks.json). Faça o seguinte:Claude Code (
.claude/):
- Revise
.claude/settings.jsone.claude/settings.local.jsonem busca de entradashooksque executem comandos shell. Sinalize qualquer coisa que execute arquivos.js,.mjsou.sh— especialmente de dentro de.claude/,.vscode/ounode_modules/.- Remova quaisquer hooks que você não consiga rastrear a um propósito legítimo criado pelo usuário.
- Adicione uma regra para impedir que seja commitado (deve permanecer local).
Audite e endureça a configuração do GitHub Actions neste repositório contra ataques à cadeia de suprimentos de CI/CD. Faça o seguinte:
Remova ou refatore quaisquer gatilhos
pull_request_target— estes executam código do workflow no contexto do repositório base com acesso a segredos, mesmo quando acionados por um fork. Substitua porpull_request+ um workflow separado com aprovação, se necessário.Fixe todas as ações de terceiros em SHAs de commit completos (não tags ou branches). Por exemplo, substitua
actions/checkout@v4poractions/checkout@<sha-completo>. Adicione um comentário com a tag para legibilidade.Aplique permissões de privilégio mínimo a cada workflow. Adicione blocos
permissions:explícitos. A maioria dos workflows precisa apenas decontents: read. Workflows de publicação precisam deid-token: write— e nada mais.Restrinja o escopo do cache: Se estiver usando
actions/cache, garanta que as chaves de cache sejam específicas do branch para evitar envenenamento entre branches. Adicionerestore-keyscom cuidado — não restaure caches de branches não confiáveis.
MIT
| # | Verificação | Descrição |
|---|
| 1 | Chave de homem morto | Daemons de persistência: gh-token-monitor (Onda 1), kitty-monitor (Onda 2) |
| 2 | Processos maliciosos | Nomes de processos conhecidos do atacante (ambas as ondas) |
| 3 | Arquivos de payload | Arquivos maliciosos conhecidos por nome e hash SHA-256 (4 hashes) |
| 4 | Hooks do Claude Code | Hooks injetados em .claude/settings.json + heurística genérica SessionStart |
| 5 | Tarefas do VS Code | Tarefas injetadas em .vscode/tasks.json + heurística genérica runOn: folderOpen |
| 6 | GitHub Actions | toJSON(secrets) em qualquer workflow + aviso de pull_request_target |
| 7 | Lockfiles npm | Versões de pacotes comprometidas em lockfiles |
| 8 | optionalDependencies | @tanstack/setup e @antv/setup maliciosos + 4 SHAs de commit impostores |
| 9 | Conexões de rede | Conexões ativas com infraestrutura C2 (5 domínios/IPs) |
| 10 | Cache DNS | Resolução anterior de domínios do atacante (4 domínios) |
| 11 | Branches Git | Padrão de nomeação de branch do atacante com tema Dune |
| 12 | Scripts de ciclo de vida | Heurística: bun run em preinstall/postinstall (pacotes instalados) |
| 13 | C2 via Dead-drop | Palavra-chave firedalazer e marcadores "Shai-Hulud" no histórico git |
| 14 | Dependências GitHub | Heurística: Dependências github: fixadas em SHA de commit em optionalDeps |
| Pacote | Versões maliciosas | Primeira versão segura |
|---|
@tanstack/react-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/router-core | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/vue-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/solid-router | 1.169.5, 1.169.8 | 1.169.9 |
@tanstack/react-start | 1.167.68, 1.167.71 | 1.167.72 |
@tanstack/router-plugin | 1.167.38, 1.167.41 | 1.167.42 |
timeago.js |
| 1.15M |
Criar um script de política de atualização: Crie um scripts/safe-update.sh que:
npm view <pkg> time --json)npm install <pkg>@latest --save-exactNão altere nenhum código de aplicação. Apenas mexa em arquivos de configuração, .npmrc, scripts de package.json e configuração do CI.
.gitignore.claude/settings.local.jsonVS Code (.vscode/):
.vscode/tasks.json e .vscode/launch.json em busca de tarefas que executem scripts ou binários inesperados.setup.mjs, router_runtime.js ou outros nomes que não pertencem a este projeto..vscode/extensions.json por extensões que você não reconhece.Cursor (.cursor/):
.cursor/settings.json e quaisquer arquivos de regras em busca de comandos ou hooks injetados..vscode/.Geral:
preinstall, postinstall, prepare ou prestart em package.json que você não escreveu. Sinalize os suspeitos..github/workflows/ por qualquer workflow que use pull_request_target — sinalize como um risco de segurança com um comentário explicando o porquê..gitignore exclua arquivos de sessão do agente que possam vazar credenciais (.claude/projects/, .cursor/logs/, etc.).Relate o que encontrou e o que alterou. Não modifique código de aplicação.
Adicione StepSecurity Harden-Runner como o primeiro passo em cada job: step-security/harden-runner@v2 com egress-policy: audit (ou block se você souber seus endpoints permitidos).
Verifique segredos nos logs do workflow: Garanta que nenhum passo do workflow imprima ${{ secrets.* }} ou ${{ toJSON(secrets) }} na saída padrão.
Relate todas as alterações. Não modifique código de aplicação.