Mini Shai-Hulud atinge AntV: mais de 300 pacotes npm maliciosos publicados por meio de uma conta comprometida de mantenedor
18 de maio de 2026
0 minutos de leituraUm ataque à cadeia de suprimentos que afeta o ecossistema de visualização de dados @antv e pacotes npm relacionados está se espalhando ativamente pelo registro npm. Atribuído ao grupo de ameaças TeamPCP e identificado como mais uma onda da campanha Mini Shai-Hulud, o ataque publicou mais de 300 versões maliciosas em 323 pacotes em uma onda automatizada de 22 minutos, em 19 de maio de 2026. Juntos, esses pacotes somam aproximadamente 16 milhões de downloads semanais.
O vetor de ataque foi uma conta comprometida de mantenedor do npm. O malware incorporado aos pacotes afetados coleta segredos de desenvolvedores e credenciais de nuvem, estabelece acesso persistente de C2 e tenta se propagar para outros pacotes usando tokens npm roubados.
Resumo
Tipo de ataque | Cadeia de suprimentos, conta de mantenedor comprometida |
Agente de ameaça | TeamPCP (aliases: DeadCatx3, PCPcat) |
Campanha | Mini Shai-Hulud (em andamento desde set. de 2025) |
Data do incidente | 19 de maio de 2026, 01:39–02:06 UTC |
Pacotes comprometidos | 637 versões maliciosas em 323 pacotes |
Estimativa de downloads semanais | ~16 milhões |
Comportamento do malware | Roubo de credenciais, coleta de segredos de nuvem, persistência e propagação do worm |
Cobertura da Snyk | Avisos na Snyk Vulnerability Database; Zero Day Report disponível no app |
Ação imediata | Fixe versões anteriores a 19 de maio, execute |
Pacotes afetados
A conta comprometida atool no npm mantinha 547 pacotes. A janela de publicação maliciosa atingiu mais de 300 deles em duas ondas:
Primeira onda: 01:39–01:56 UTC (~317 versões)
Segunda onda: 02:05–02:06 UTC (~314 versões)
Entre os pacotes afetados com mais downloads estão:
Pacote | Snyk Advisor | Downloads mensais |
| 4,2 milhões | |
| 3,8 milhões | |
| 2,2 milhões | |
| 1,15 milhão | |
| Mais de 1 milhão |
Entre os principais pacotes @antv comprometidos estão @antv/g2, @antv/g6, @antv/x6, @antv/l7, @antv/s2, @antv/f2, @antv/g, @antv/g2plot, @antv/graphin e @antv/data-set, além de pacotes sem escopo, como echarts-for-react, timeago.js, size-sensor e canvas-nest.js.
A AntV é um conjunto de ferramentas de visualização de dados que teve origem na Alibaba e é amplamente usado em painéis corporativos, ferramentas de relatórios financeiros e plataformas de análise de grafos. Sua ampla adoção torna o portfólio de pacotes da conta de mantenedor um alvo de valor excepcionalmente alto.
Como o ataque funciona
Etapa 1: comprometimento da conta de mantenedor
O ataque começa com o comprometimento da conta atool no npm. A forma como a conta foi obtida ainda está sob investigação. Com o controle da conta, o invasor podia publicar em todos os 547 pacotes mantidos por ela.
Etapa 2: publicação automatizada de código malicioso
O invasor publicou versões maliciosas em duas ondas rápidas, enviando a maioria dos pacotes duas vezes (alguns pacotes usados nos primeiros testes receberam três versões). Cada arquivo tarball de pacote malicioso contém duas adições:
Um
index.js:na raiz: um payload JavaScript de 498 KB para Bun, altamente ofuscadoUma alteração em
package.json, adicionando:"preinstall": "bun run index.js"
O hook de ciclo de vida preinstall é acionado automaticamente quando um desenvolvedor executa npm install, antes da execução de qualquer outra lógica de instalação.
Etapa 3: injeção de commit órfão para comprovação de origem do Sigstore
Uma das técnicas mais sutis desta onda é a injeção de uma dependência opcional que aponta para um commit órfão no repositório legítimo antvis/G2:
É importante observar que a dependência obtida do GitHub usa o mesmo método de ataque empregado no ataque anterior à cadeia de suprimentos TanStack Shai-Hulud.
O commit foi criado pelo invasor, mas falsificado para parecer ter sido escrito por huiyu.zjt <huiyu.zjt@ant.com> (um mantenedor real). Não foi necessário ter acesso de gravação ao repositório alvo. O invasor criou um fork de antvis/G2, fez um commit órfão contendo o payload e depois excluiu o fork. O armazenamento de objetos do GitHub mantém commits de forks excluídos até que ocorra a coleta de lixo, deixando o commit malicioso acessível por seu hash.
A obtenção desse commit oferece um caminho para executar o payload usando credenciais obtidas do Git, dando a impressão de que ele faz referência a um repositório confiável.
Em seguida, usando tokens OIDC roubados do GitHub Actions, o malware pode solicitar certificados de assinatura ao Fulcio (https://fulcio.sigstore.dev) e criar declarações de proveniência in-toto por meio do Rekor (https://rekor.sigstore.dev), gerando pacotes com atestações SLSA Build Level 3 criptograficamente válidas.
O ponto principal é que as assinaturas são legítimas porque o próprio pipeline de build foi comprometido. A proveniência do Sigstore informa qual pipeline produziu um artefato, não se esse pipeline estava se comportando como deveria. Por isso, é um equívoco comum acreditar que as evidências de atestação, por si só, comprovam de forma incontestável a legitimidade de pacotes publicados.
Etapa 4: coleta de credenciais
Quando bun run index.js é executado no computador de um desenvolvedor ou em um executor de CI, o payload busca informações em mais de 80 variáveis de ambiente e mais de 100 caminhos de arquivos. Entre os tipos de credenciais visados estão:
AWS: chaves de acesso (
AKIA[0-9A-Z]{16}), tokens de sessão, EC2 IMDS (169.254.169.254), metadados do ECS (169.254.170.2), Secrets ManagerGCP: JSON de conta de serviço, credenciais padrão de aplicativos
Azure: credenciais de entidade de serviço
GitHub: PATs e tokens OIDC (
gh[op]_[A-Za-z0-9]{36,})npm: tokens de publicação com escopo
bypass_2faInfraestrutura: tokens de serviço do Kubernetes, tokens do HashiCorp Vault
Bancos de dados: strings de conexão do MongoDB, MySQL, PostgreSQL e Redis
Serviços: chaves do Stripe, tokens do Slack, configurações de autenticação do Docker
Chaves SSH:
~/.ssh/id_*
Em ambientes do GitHub Actions, o payload tenta ler segredos diretamente da memória do processo Runner.Worker por meio de /proc/{pid}/mem, contornando completamente a ocultação de segredos.
Etapa 5: exfiltração de dados
Todas as credenciais coletadas são serializadas como JSON, compactadas com gzip, criptografadas com AES-256-GCM e, em seguida, a chave de criptografia é protegida com RSA-OAEP usando uma chave pública do invasor codificada no malware. Isso significa que defensores que encontrarem os dados exfiltrados não conseguirão determinar o que foi roubado.
A exfiltração ocorre por dois canais:
C2 principal:
https://t[.]m-kosche[.]com:443/api/public/otel/v1/traces(disfarçado de dados de rastreamento do OpenTelemetry)Repositório de descarte secundário no GitHub: se um token do GitHub for encontrado, o payload cria repositórios na conta da vítima com nomes inspirados em Duna (combinações de palavras como
sardaukar,fremen,atreidescomsandworm,ornithopter,stillsuit, além de um número entre 0 e 999). Esses repositórios contêm arquivos README com frases características de ondas anteriores da campanha Shai-Hulud, escritas ao contrário (por exemplo, “niagA oG eW ereH :duluH-iahS”). Os dados roubados são enviados em commits comoresults/results-<timestamp>-<counter>.json. As solicitações HTTP usam"python-requests/2.31.0"como User-Agent.
Etapa 6: persistência
O payload instala vários mecanismos de persistência que continuam ativos mesmo após um simples npm uninstall:
Sequestro de agentes de programação com IA: cria
.claude/settings.jsoncom um hookSessionStartque executanode .claude/setup.mjs. Isso volta a executar o malware sempre que um desenvolvedor abre uma nova sessão do Claude Code em um diretório afetado. Vale notar que esse padrão também é semelhante ao que observamos em campanhas anteriores de ataque à cadeia de suprimentos, como a da TanStack.Hooks de IDE: altera
.vscode/tasks.jsoncom"runOn": "folderOpen"para ser acionado quando o projeto é aberto.Daemon no nível do sistema operacional: instala
~/.local/share/kitty/cat.py, um daemon em segundo plano que consulta de hora em hora a API de pesquisa de commits do GitHub em busca de comandos com a palavra-chavefiredalazer. Os comandos são assinados com RSA-PSS usando uma chave pública de 4096 bits codificada no malware, permitindo que o invasor envie qualquer código Python para ser executado em máquinas comprometidas muito depois da infecção inicial. No Linux, o daemon é registrado como um serviço de usuário do systemd (~/.config/systemd/user/kitty-monitor.service) e, no macOS, como um LaunchAgent (~/Library/LaunchAgents/com.user.kitty-monitor.plist).
Monitor de tokens: ~/.local/bin/gh-token-monitor.sh consulta os tokens roubados do GitHub a cada 60 segundos, permitindo que o invasor reaja rapidamente quando um token estiver prestes a expirar.
Etapa 7: propagação do worm
O payload procura tokens npm com o escopo bypass_2fa e os usa para republicar outros pacotes que a conta comprometida pode publicar. Em ambientes do GitHub Actions, ele troca o token OIDC do Actions por tokens de publicação npm específicos para cada pacote por meio de:
Ele também injeta um workflow do GitHub Actions em uma branch chamada chore/add-codeql-static-analysis, com o arquivo do workflow chamado "Run Copilot" (.github/workflows/codeql.yml). O workflow despeja toJSON(secrets) em um artefato chamado format-results.txt e depois apaga os próprios rastros, excluindo a execução do workflow.
Análise do impacto
O impacto direto abrange qualquer ambiente de desenvolvedor ou de CI que tenha executado npm install com uma versão afetada de um pacote entre 01:39 e aproximadamente 02:18 UTC de 19 de maio de 2026.
Ambientes de CI/CD correm risco elevado. Neles, o payload pode ler todos os segredos do processo do executor, não apenas os que foram passados explicitamente como variáveis de ambiente. Se uma versão afetada foi instalada, considere comprometido qualquer segredo ao qual o executor do GitHub Actions tenha acesso, incluindo tokens OIDC, segredos do repositório e segredos da organização com escopo para esse repositório.
Os computadores dos desenvolvedores também correm um risco significativo. Os mecanismos de persistência fazem com que apenas remover os pacotes afetados não elimine a ameaça. O hook .claude/settings.json, a tarefa do VS Code e o daemon do sistema continuam em execução até serem removidos explicitamente.
O componente de autopropagação significa que qualquer token npm capturado de um computador de desenvolvedor ou executor de CI pode ser usado para comprometer outros pacotes fora do portfólio inicial da conta atool, ampliando o impacto para além da AntV e dos pacotes relacionados.
Detecção
Verifique seu arquivo de lock. Se o arquivo package-lock.json ou yarn.lock fizer referência a algum pacote mantido pela conta atool, confira se a versão resolvida foi publicada entre 01:39 e 02:18 UTC de 19 de maio de 2026.
Use a Snyk para analisar seus projetos. A Snyk publicou avisos na Snyk Vulnerability Database para as versões afetadas dos pacotes e disponibilizou uma notificação no app e um Zero Day Report para que clientes investiguem a exposição em suas organizações.
Para analisar rapidamente um pacote específico na sua árvore de dependências:
Verifique se há artefatos de persistência. Se você instalou algum pacote afetado, procure por:
Indicadores no nível do pacote:
Presença do script
preinstallbun run index.jsemnode_modules/<package>/package.jsonSHA256 do payload:
a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1cDependência opcional que referencia
github:antvis/G2#1916faa365f2788b6e193514872d51a242876569(ou os commits7cb42f57561c / dc3d62a2181b)
Indicadores de rede:
Requisições de saída para
169.254.169.254ou169.254.170.2(endpoints de metadados de nuvem) em contextos que não são de nuvemRequisições HTTP para
t.m-kosche.com:443com caminhos do OpenTelemetryChamadas à API do GitHub com o User-Agent
python-requests/2.31.0que não se originam de processos Python reais
Como remediar
Se você não tiver certeza de que foi afetado, considere que houve um comprometimento confirmado. Como a exfiltração foi criptografada com RSA, não é possível recuperar o que foi roubado.
Etapa 1: Remova os mecanismos de persistência antes de revogar os tokens.
O daemon gh-token-monitor.sh verifica os tokens a cada 60 segundos. Se um token do GitHub expirar ou for revogado enquanto o daemon estiver em execução, isso poderá desencadear outras ações maliciosas. Primeiro, interrompa e remova os mecanismos de persistência:
Etapa 2: Limpe o npm e reinstale usando versões confiáveis.
O uso de --ignore-scripts impede a execução de scripts de ciclo de vida preinstall, postinstall ou prepare durante a instalação. De qualquer forma, essa deve ser uma prática padrão em ambientes de CI.
Etapa 3: Troque todas as credenciais.
Considere comprometido tudo o que estiver acessível por qualquer máquina ou executor de CI que tenha instalado um pacote afetado:
Tokens de publicação do npm
Tokens de acesso pessoal do GitHub e secrets do Actions
Chaves de acesso da AWS (e quaisquer funções do IAM acessíveis pelos executores afetados)
Chaves de contas de serviço do GCP
Principais de serviço do Azure
Tokens de contas de serviço do Kubernetes
Tokens do HashiCorp Vault
Chaves SSH presentes nas máquinas afetadas
Strings de conexão com bancos de dados
Quaisquer chaves de API ou tokens de serviço armazenados em variáveis de ambiente ou arquivos de configuração
Etapa 4: Audite o GitHub em busca de workflows injetados e repositórios usados como pontos de entrega.
Etapa 5: Evite futuras exposições.
Ative a autenticação de dois fatores do npm com proteção de publicação em todos os pacotes da organização.
Adicione
npm install --ignore-scriptsà configuração de CI como padrão.Fixe as dependências em versões exatas usando arquivos de lock com verificações de integridade.
Considere uma política de período de espera no registro: sinalize e retenha os pacotes publicados nos últimos 7 dias.
Use o Snyk para monitorar continuamente sua árvore de dependências e identificar pacotes maliciosos assim que forem sinalizados.
Recomendamos fortemente que você consulte e siga o repositório de práticas recomendadas de segurança do npm para adotar controles e práticas que ajudem a evitar futuros incidentes de malware.
A campanha mais ampla: ondas do Shai-Hulud
O ataque ao AntV é a onda mais recente de uma campanha conduzida pelo TeamPCP desde setembro de 2025. A evolução demonstra uma escalada constante em escopo, persistência, sofisticação e abuso de infraestruturas confiáveis:
Onda | Data | Alvo principal | Escala | Técnica característica |
Onda 1 (Shai-Hulud) | set. de 2025 | npm (amplo) | ~4 pacotes | Primeiro worm do npm com propagação automática |
Onda 2 (SHA1-Hulud) | nov. de 2025 | Zapier, Posthog, Postman | Mais de 600 pacotes | Escape de contêineres; malware destrutivo de limpeza |
Onda 3 (Mini, SAP) | abr. de 2026 | SAP CAP-JS, MBT | 4 pacotes | Injeção de hook |
Onda 4 (TanStack) | 11 de mai. de 2026 | @tanstack/* | 84 versões/42 pacotes | Primeira procedência SLSA válida obtida por sequestro de OIDC |
Onda 5 (AntV) | 19 de mai. de 2026 | @antv/* + mais 310 | 637 versões/323 pacotes | Conta de mantenedor comprometida; C2 ampliado |
A Snyk analisou em detalhes as ondas anteriores:
Cada onda reutilizou e ampliou o payload ofuscado baseado no runtime Bun, acrescentando novos mecanismos de persistência (o hook SessionStart do Claude Code apareceu pela primeira vez na Onda 3), novas infraestruturas de exfiltração e novos métodos para forjar procedências confiáveis. O problema da procedência SLSA merece atenção especial: uma atestação válida do Sigstore confirma qual pipeline produziu um pacote, mas não se esse pipeline foi comprometido. Confiar na procedência como sinal de confiança sem também auditar a configuração do pipeline subjacente deixa uma brecha que esta campanha já explorou em duas ondas consecutivas.
Veja um passo a passo em vídeo da remediação com o Snyk para a campanha mais ampla do Shai-Hulud:

Ataque Shai-Hulud ao NPM: remediação com o Snyk — passo a passo para identificar e remediar pacotes comprometidos usando as ferramentas do Snyk.
Cronologia do ataque (19 de maio de 2026, UTC)
Horário | Evento |
01:39 | Primeira versão maliciosa do pacote publicada pela conta |
01:56 | Fim da primeira onda de publicações (~317 versões) |
02:05 | Início da segunda onda |
02:06 | Fim da segunda onda (~314 versões adicionais) |
~02:18 | Detecção; pesquisadores de segurança começam a enviar denúncias |
Em andamento | A investigação continua; outros pacotes podem ser identificados |
Cobertura da Snyk
A Snyk publicou avisos sobre as versões afetadas dos pacotes na Snyk Vulnerability Database. Clientes da Snyk podem usar o Zero Day Report no aplicativo para investigar quais projetos da organização foram afetados. As entradas dos pacotes afetados na Snyk Vulnerability Database refletem o estado atual da análise.
Para entender melhor esse tipo de ataque, a lição do Snyk Learn sobre comprometimento de pacotes legítimos explica como o comprometimento de contas de mantenedores se insere no contexto mais amplo das ameaças à cadeia de suprimentos.
Proteja sua cadeia de suprimentos com a Snyk
87% dos entrevistados foram afetados por problemas de segurança na cadeia de suprimentos. Mantenha a sua protegida com a Snyk.
