
Campanha atribuída ao TeamPCP inseriu stealers em pacotes de TanStack, Mistral AI, Guardrails AI, UiPath e outros projetos, com exfiltração de credenciais, persistência em IDEs e abuso de identidades de CI/CD.
| Componente | Pacotes npm e PyPI associados a TanStack, UiPath, Mistral AI, OpenSearch, Guardrails AI, DraftLab e outros mantenedores, incluindo 42 pacotes e 84 versões no ecossistema TanStack. |
| Vetor | Publicação de pacotes adulterados por fluxos de CI/CD e identidades de publicação confiável, com execução por preinstall, prepare, dependência opcional hospedada no GitHub, Bun, Node.js ou execução em importação Python. |
| Impacto | Roubo de credenciais de nuvem, carteiras de criptomoedas, ferramentas de IA, aplicativos de mensagens, GitHub, sistemas de CI e segredos de repositório; exfiltração para filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com, GitHub API e infraestrutura remota. |
| Prioridade | Isolar máquinas de desenvolvedores e runners afetados antes de revogar tokens, preservar imagem forense, remover pacotes comprometidos, rotacionar credenciais e revisar fluxos GitHub Actions com OIDC e pull_request_target. |
| Versões | O comprometimento TanStack foi associado ao identificador CVE-2026-45321, com severidade crítica e pontuação CVSS 9.6; a onda total afetou mais de 170 pacotes em npm e PyPI. |
| Artefatos | Arquivo JavaScript ofuscado router_init.js, execução de node setup.mjs, artefato Python https://git-tanstack.com/transformers.pyz, persistência em Claude Code e Visual Studio Code, serviço gh-token-monitor e workflows maliciosos do GitHub Actions. |
| IoCs | filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com, 83.142.209[.]194, repositórios contendo Shai-Hulud: Here We Go Again e commits atribuídos a claude@users.noreply.github.com. |
A campanha Mini Shai-Hulud ampliou um comprometimento de cadeia de suprimentos para pacotes distribuídos por npm e PyPI, atingindo projetos ligados a TanStack, Mistral AI, Guardrails AI, UiPath, OpenSearch, DraftLab e outros mantenedores. O operador associado à atividade, identificado como TeamPCP, não se limitou a publicar versões adulteradas: a cadeia observada combina código malicioso em pacotes, abuso de fluxos de publicação, roubo de tokens, propagação entre pacotes do mesmo mantenedor e exfiltração redundante de credenciais. A superfície de risco é alta porque a instalação ou importação de um pacote comprometido ocorre dentro de estáções de desenvolvimento, pipelines e runners com acesso a segredos operacionais, credenciais de nuvem e permissões de publicação.
Nos pacotes npm, o payload foi distribuído por um arquivo JavaScript ofuscado, router_init.js, criado para perfilar o ambiente de execução e iniciar um stealer abrangente. O código procura credenciais associadas a provedores de nuvem, carteiras de criptomoedas, ferramentas de IA, aplicativos de mensagens, GitHub Actions e outros sistemas de CI. A exfiltração principal usa o domínio filev2.getsession[.]org, associado a infraestrutura do Session Protocol, o que dificulta bloqueios genéricos em ambientes corporativos porque o domínio pode parecer vinculado a um serviço legítimo de mensageria privada. Quando essa rota não funciona, o malware grava dados cifrados em repositórios controlados pelo atacante via GitHub GraphQL API, usando tokens GitHub roubados e o autor claude@users.noreply.github.com.
O caso TanStack recebeu o identificador CVE-2026-45321, com CVSS 9.6, e envolveu 42 pacotes e 84 versões no ecossistema do projeto. A onda completa ultrapassou 170 pacotes nos registros npm e PyPI, com mais de 518 milhões de downloads acumulados, e resultou na criação de pelo menos 400 repositórios contendo credenciais furtadas e a string Shai-Hulud: Here We Go Again. O dado operacional mais importante para defesa é que alguns artefatos carregam sinais de publicação aparentemente legítima, inclusive atestações SLSA Build Level 3 em pacotes maliciosos, o que reduz a utilidade de validações que confiam apenas na presença de proveniência sem avaliar o comportamento do build e a origem exata do fluxo que emitiu o token de publicação.
A campanha usa mais de um caminho de execução. Em ondas anteriores, o comprometimento dependia de hooks preinstall para acionar a infecção durante a instalação do pacote. No agrupamento TanStack, a estratégia mudou: o pacote npm inclui um JavaScript malicioso dentro do tarball e declara uma dependência opcional que aponta para um pacote hospedado no GitHub. Essa dependência contém um hook prepare que executa o payload JavaScript com o runtime Bun. Já nos pacotes da Mistral AI, a técnica observada substitui o conteúdo de package.json por um hook preinstall que chama node setup.mjs; esse script baixa Bun e executa o mesmo malware JavaScript. Essa diferença exige hunting tanto em scripts de ciclo de vida quanto em dependências opcionais e artefatos incluídos diretamente no pacote publicado.
O comprometimento do TanStack foi rastreado para uma cadeia envolvendo GitHub Actions com pull_request_target, envenenamento de cache do GitHub Actions e extração em memória de um token OIDC do processo do runner. O atacante preparou o payload em um fork por meio de um commit órfão, inseriu o conteúdo em tarballs npm publicados e sequestrou o fluxo legítimo TanStack/router para publicar versões comprometidas com proveniência válida. A publicação não exigiu roubo direto de tokens npm nem comprometimento do workflow de publicação em si; a falha operacional ficou na capacidade de código controlado pelo atacante executar em um contexto com confiança suficiente para trocar a identidade OIDC por um token curto de publicação. Em configurações nas quais a relação de confiança do publicador OIDC é definida no nível do repositório, sem amarração rigorosa a ramo protegido e arquivo de workflow específico, uma execução inesperada ainda pode receber autoridade para publicar.
O worm também possui lógica de propagação. Ele procura tokens npm publicáveis com bypass_2fa definido como verdadeiro, enumera pacotes mantidos pela mesma conta e tenta trocar um token OIDC do GitHub por tokens de publicação por pacote, evitando autenticação tradicional. Essa técnica desloca o risco do segredo estático para a identidade transitória da pipeline: mesmo sem um token npm persistente exposto, uma execução maliciosa dentro de um workflow confiável pode receber credenciais temporárias suficientes para empacotar e distribuir código. Em paralelo, o malware instala persistência em Claude Code e Microsoft Visual Studio Code para reexecutar o stealer a cada inicialização das IDEs, cria o serviço gh-token-monitor para monitorar e reenviar tokens GitHub e injeta dois workflows GitHub Actions que serializam segredos de repositório em JSON e enviam os dados para api.masscan[.]cloud.
Nos pacotes PyPI, a família apresenta diferenças relevantes. O pacote guardrails-ai@0.10.1 foi destacado porque o código malicioso executa na importação, sem depender somente de instalação. Em sistemas Linux, ele baixa https://git-tanstack.com/transformers.pyz, grava o arquivo em /tmp/transformers.pyz e o executa com python3, sem verificação de integridade. Na análise do pacote malicioso mistralai em PyPI, o código baixa um stealer a partir de 83.142.209[.]194, inclui lógica para evitar ambientes em idioma russo e possui um ramo destrutivo georrestrito com chance de executar rm -rf / quando o sistema parece estar em Israel ou no Irã. Essa função destrutiva transforma parte da campanha em risco de indisponibilidade, não apenas de vazamento.
A superfície exposta inclui estáções de desenvolvedores, ambientes de build, runners de CI/CD, caches do GitHub Actions, repositórios com segredos, pacotes publicados por mantenedores impactados e ambientes que instalam dependências de forma automática. Projetos que consomem versões comprometidas podem executar o payload durante npm install, durante hooks de preparação de dependências, durante importação Python ou em rotinas de build que resolvem dependências sem pinagem estrita. A exposição aumenta quando pipelines possuem variáveis sensíveis, tokens GitHub com escopo amplo, credenciais de provedores de nuvem, chaves de publicação, acesso a registros de pacotes e permissões para acionar novos workflows.
A campanha também afeta controles de confiança de software. Pacotes publicados pelo próprio workflow legítimo do projeto podem carregar metadados de proveniência válidos e, ainda assim, conter conteúdo malicioso se o fluxo que emitiu a identidade OIDC foi induzido a executar código adversário. Por isso, lockfiles, hashes de artefatos, SBOMs, atestações SLSA e políticas de trusted publishing precisam ser avaliados em conjunto com escopo do workflow, ramo permitido, origem do evento, conteúdo do tarball e comportamento em instalação. Ambientes que tratam proveniência como aprovação automática ficam vulneráveis quando o problema está na execução que gerou a proveniência, e não apenas no canal de publicação.
- Pacotes TanStack afetados por
CVE-2026-45321, com 42 pacotes e 84 versões publicados de forma comprometida. - Pacotes npm com
router_init.js, dependência opcional hospedada no GitHub, hookprepare, Bun oupreinstallchamandonode setup.mjs. - Pacotes PyPI associados a Mistral AI e Guardrails AI, incluindo execução em importação no caso de
guardrails-ai@0.10.1. - Runners GitHub Actions com uso de
pull_request_target, cache compartilhado e confiança OIDC não restringida a ramo protegido e arquivo de workflow específico. - Estáções com Claude Code ou Visual Studio Code, nas quais a persistência do stealer pode sobreviver a reinicializações e novas sessões de desenvolvimento.
A investigação deve começar por inventário de dependências, lockfiles e caches de pacote. Em npm, compare versões instaladas e resolvidas contra listas internas de pacotes afetados, procure scripts preinstall, prepare e dependências opcionais incomuns, e extraia tarballs para localizar router_init.js ou JavaScript ofuscado não esperado. Em PyPI, busque artefatos que executem código durante importação, downloads remotos para transformers.pyz, gravações em /tmp/transformers.pyz e chamadas a python3 originadas por módulos de dependência. A ausência de erro de instalação não reduz o risco, porque o payload foi projetado para operar dentro de fluxos legítimos e exfiltrar silenciosamente dados do ambiente.
Na camada de rede, monitore conexões para filev2.getsession[.]org, api.masscan[.]cloud, git-tanstack[.]com e 83.142.209[.]194. Também é necessário inspecionar uso incomum da GitHub GraphQL API, criação de repositórios por contas de desenvolvedores, commits com autor claude@users.noreply.github.com, repositórios contendo Shai-Hulud: Here We Go Again e workflows adicionados sem revisão humana. Em endpoints, colete evidências de serviços persistentes com nome gh-token-monitor, alterações em diretórios de configuração do Claude Code e VS Code, scripts shell que consultam api.github.com/user a cada 60 segundos e tokens npm com descrição IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner..
A telemetria de CI/CD precisa responder a perguntas específicas: qual evento acionou o workflow, qual ramo ou commit foi usado, se o commit era órfão, quais caches foram restaurados, quais permissões OIDC foram concedidas, qual identidade solicitou token de publicação e qual pacote foi publicado em seguida. Eventos pull_request_target merecem atenção especial quando executam código derivado de forks, restauram cache controlável por contribuidor externo ou rodam etapas com permissão de escrita. Para repositórios com trusted publishing, valide se o provedor npm ou PyPI exige repositório, ramo protegido e caminho exato do workflow, e se há publicações recentes feitas por execuções não esperadas.
- Requisições DNS ou HTTP para
filev2.getsession[.]org,api.masscan[.]cloud,git-tanstack[.]come83.142.209[.]194. - Presença de
router_init.js,setup.mjs,/tmp/transformers.pyz, Bun baixado por scripts de pacote ou execução depython3iniciada por importação de dependência. - Criação de workflows GitHub Actions que leem segredos, serializam variáveis em JSON ou enviam conteúdo para servidor externo.
- Uso anômalo da GitHub GraphQL API com tokens de desenvolvedor, criação de repositórios inesperados e commits atribuídos a
claude@users.noreply.github.com. - Tokens npm com
bypass_2faverdadeiro, tokens GitHub recém-criados, descrições ameaçadoras em tokens e chamadas periódicas aapi.github.com/user.
A resposta deve evitar revogação precipitada quando houver indicação do token com mecanismo destrutivo. O malware instala um dead man's switch que verifica periodicamente se um token npm criado por ele continua válido; caso o desenvolvedor revogue esse token diretamente pelo painel npm, o script pode executar rm -rf ~/ na máquina infectada. A primeira ação defensiva é desconectar o host da rede, preservar memória e disco quando possível, coletar artefatos de persistência, identificar processos em execução e somente depois revogar tokens a partir de um ambiente limpo. Para hosts com indício do ramo destrutivo em PyPI, trate o caso como incidente com risco de destruição local e priorize contenção física ou lógica antes de qualquer interação com credenciais.
Depois da contenção, remova versões comprometidas de caches internos, registros espelhados, imagens de build e ambientes de desenvolvimento. Recrie lockfiles a partir de versões verificadas, invalide caches do GitHub Actions associados ao período de comprometimento e reconstrua artefatos de produção que tenham consumido dependências afetadas. Rotacione tokens GitHub, npm, PyPI, credenciais de nuvem, chaves de carteiras, tokens de mensagens e segredos de CI que estiveram disponíveis em hosts, runners ou workflows expostos. A rotação deve considerar segredos lidos indiretamente por workflows injetados, não apenas arquivos presentes no endpoint.
Na prevenção, restrinja trusted publishing por repositório, ramo protegido e arquivo exato de workflow, reduza permissões padrão de GITHUB_TOKEN, exija revisão para alterações em workflows, desabilite ou limite pull_request_target quando etapas executarem conteúdo de fork e isole caches usados por contribuições externas. Workflows de publicação devem separar build, teste e publicação em contextos com permissões distintas; etapas que resolvem dependências de fork não devem ter acesso a OIDC capaz de emitir token de publicação. Em endpoints de desenvolvimento, monitore alterações em configurações de IDE, bloqueie execução automática de scripts de pacote quando o fluxo permitir e aplique allowlists de registros e domínios de download para builds reproduzíveis.
- Isolar hosts e runners suspeitos antes de revogar tokens npm quando houver indício do token com descrição
IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner.. - Coletar imagem, memória, histórico de shell, processos, serviços, tarefas persistentes e alterações em Claude Code e Visual Studio Code.
- Remover pacotes afetados de caches locais, proxies de dependência, imagens de CI e ambientes de build; reconstruir a partir de versões verificadas.
- Rotacionar tokens GitHub, npm, PyPI, credenciais de nuvem, segredos de repositório e chaves expostas a pipelines ou estáções comprometidas.
- Restringir OIDC e trusted publishing a ramo protegido e workflow específico, revisar uso de
pull_request_targete invalidar caches do GitHub Actions do período afetado.
0 Comentários