Incidente · Comprometimento de pacote npm
O comprometimento do Nx no npm: o que fez no Mac de um desenvolvedor e o que o Kilobat teria mostrado
Por cerca de cinco horas em 26 e 27 de agosto de 2025, oito versões do sistema de build Nx no npm continham um script postinstall que procurava segredos nas máquinas de desenvolvedores, recorria às CLIs de programação com IA que encontrava e publicava o material coletado em um novo repositório público na própria conta GitHub da vítima.
Em resumo
- Protection: Não ajudaria
Nada a bloquear. O código veio de registry.npmjs.org e os dados foram para api.github.com, que não constam em nenhuma lista de ameaças.
- Agent guard: Não ajudaria
Não houve site para colar conteúdo, túnel nem endereço IP direto, e o bloqueio de upload deixa de fora hosts conhecidos como api.github.com, intencionalmente.
- Registro de rede de agentes: Limitado
Ele teria registrado um script de instalação se comunicando com a API do GitHub e as execuções das CLIs de IA iniciadas pelo script, mas somente para instalações neste Mac e sem bloqueá-las.
O que aconteceu
O atacante obteve o token de publicação npm do Nx por meio da própria CI do projeto. Segundo o aviso dos mantenedores, um workflow do GitHub Actions integrado em 21 de agosto usava o gatilho pull_request_target e enviava títulos de pull requests a um shell, permitindo que um título preparado executasse comandos com as permissões do repositório. Em 24 de agosto, esse caminho foi usado para iniciar o workflow de publicação a partir de um commit malicioso e enviar o token npm a um webhook.
Com o token, o atacante publicou nx 20.9.0–20.12.0 e 21.5.0–21.8.0, além de versões de @nx/devkit, @nx/js, @nx/workspace, @nx/node, @nx/eslint, @nx/key e @nx/enterprise-cloud. Cada uma continha um hook postinstall que executava telemetry.js, que só agia no macOS e Linux.
O script procurava as ferramentas de linha de comando claude, gemini e q e, quando instaladas, executava-as com as flags que ignoram as solicitações de permissão (--dangerously-skip-permissions, --yolo, --trust-all-tools) e um prompt pedindo que listassem em /tmp/inventory.txt arquivos que parecessem ser carteiras, chaves e arquivos .env. A Snyk e a StepSecurity publicaram o código. A Wiz observou que isso funcionou em centenas de casos, embora as proteções dos provedores de IA tenham recusado algumas solicitações.
Em seguida, ele leu esses arquivos, coletou o token da CLI do GitHub com gh auth token e o token npm de ~/.npmrc, criou um repositório público chamado s1ngularity-repository na conta da vítima e enviou tudo como results.b64 codificado três vezes em base64. Também acrescentou sudo shutdown -h 0 a ~/.zshrc e ~/.bashrc, fazendo com que cada novo terminal pedisse uma senha e desligasse a máquina.
Muitas instalações não foram digitadas por ninguém. Os mantenedores descobriram que a extensão de editor Nx Console, versões 18.6.30 a 18.65.1, verificava a versão mais recente de nx ao iniciar; portanto, bastava abrir um editor durante esse período. A Wiz também encontrou o malware em execução em pipelines de CI. A Wiz contou mais de mil tokens GitHub válidos entre os dados vazados; em uma segunda fase, tokens roubados foram usados para tornar públicos mais de 5.500 repositórios privados.
Linha do tempo
- 21 ago. 2025
Um workflow com uma falha de injeção no shell é integrado ao repositório Nx (aviso dos mantenedores).
- 24 ago. 2025
Um pull request preparado inicia o workflow de publicação a partir de um commit malicioso, que envia o token npm a um webhook.
- 26 ago., 22:32 UTC
nx21.5.0 e vários pacotes@nx/*são publicados comtelemetry.js; 20.9.0 é publicado sete minutos depois. - 27 ago., 00:30 UTC
Um usuário abre uma issue no GitHub sobre as versões maliciosas. As duas últimas, 21.8.0 e 20.12.0, aparecem às 00:37.
- 27 ago., 02:44 UTC
O npm remove as versões afetadas e os tokens de publicação.
- 27 ago., por volta de 09:00 UTC
O GitHub desativa os repositórios criados pelo atacante, cerca de oito horas após o aparecimento dos primeiros (Wiz).
- 27 ago. 2025
O Nx Console 18.66.0 deixa de instalar a versão mais recente de
nx; o Nx transfere a publicação para o Trusted Publishers do npm com 2FA. - 28–29 ago. 2025
Tokens roubados são usados para renomear repositórios privados e torná-los públicos; a Wiz contabiliza mais de 400 contas e 5.500 repositórios.
Como apareceu na rede
Em um Mac, o ataque usou dois hosts com os quais a máquina de um desenvolvedor se comunica todos os dias. O pacote veio de registry.npmjs.org, como qualquer outro. O material roubado foi para api.github.com, em nome da vítima, usando o próprio token da CLI do GitHub dela: um POST /user/repos para criar o repositório, seguido de um PUT /repos/<owner>/s1ngularity-repository/contents/results.b64 com os dados codificados. Não havia servidor de comando e controle nem outro destino de upload.
A árvore de processos era curta. npm (ou a extensão do editor) executava um shell, o shell executava node telemetry.js e o node iniciava claude, gemini ou q como processos filhos. Cada CLI de IA se comunicava com seu próprio provedor, como no uso normal; a leitura dos arquivos ocorria localmente. O upload em si partia do node. Seu tamanho dependia inteiramente do conteúdo dos arquivos.
Indicadores
Conforme documentados pelas fontes. Os domínios aparecem como texto, nunca como links, e são neutralizados ([.]) quando a fonte os neutraliza. A maior parte dessa infraestrutura já deixou de existir: os indicadores ajudam a verificar registros, arquivos e contas antigos, não a bloquear campanhas atuais.
| Indicador | Tipo | Onde aparece | Observação |
|---|---|---|---|
api.github.com | Host (legítimo) | Seu Mac | POST /user/repos, seguido de PUT …/contents/results.b64, feitos pelo node durante uma instalação npm. |
s1ngularity-repository, s1ngularity-repository-0, s1ngularity-repository-1 | Nome do repositório GitHub | Conta GitHub | Públicos quando criados; o GitHub os desativou em 27 de agosto. Os repositórios renomeados na segunda fase usavam s1ngularity-repository- seguido de cinco letras. |
results.b64 | Arquivo | Repositório GitHub | Os dados coletados, codificados em base64 duas ou três vezes. |
/tmp/inventory.txt, /tmp/inventory.txt.bak | Arquivo | Seu Mac | A lista de caminhos de arquivos das CLIs de IA. |
sudo shutdown -h 0 | Linha em ~/.zshrc, ~/.bashrc | Seu Mac | Desliga o Mac quando um terminal é aberto e a senha é informada. |
nx 20.9.0–20.12.0, 21.5.0–21.8.0 | Versões npm | Lockfiles, cache do npm | Também @nx/devkit, @nx/js, @nx/workspace, @nx/node 20.9.0 e 21.5.0, @nx/eslint 21.5.0, @nx/key e @nx/enterprise-cloud 3.2.0. |
O que o Kilobat teria mostrado ou bloqueado
- Registro de rede de agentes. Quando um agente executava a instalação, por exemplo, o Claude Code executando
npm install, sua sessão listarianodesobnpmenviando dados paraapi.github.comdurante uma instalação: vale examinar um script de instalação que se comunica com a API do GitHub. Ele não seria sinalizado como primeira vez, pois api.github.com é um host conhecido, e só seria sinalizado como upload grande acima de 10 MB. - Registro de rede de agentes. O Kilobat reconhece o Claude Code e o Gemini CLI pelos executáveis, independentemente de quem os iniciou; assim, as execuções iniciadas pelo script apareceriam como sessões próprias, na pasta do projeto, em um momento em que você não havia iniciado um agente. O
qda Amazon não é um dos agentes reconhecidos pelo Kilobat. - Protection. Nada. registry.npmjs.org e api.github.com não são ameaças, e o Kilobat nunca deve bloqueá-los.
- Proteção de agentes. Também nada. As regras da proteção cobrem sites para colar conteúdo, compartilhamentos de arquivos, túneis, coletores de requisições e endereços IP diretos, nenhum dos quais apareceu; seu bloqueio de upload ignora hosts conhecidos para que
git pushcontinue funcionando.
Onde o Kilobat não teria ajudado
- A exfiltração para github.com com o próprio token da vítima se parece com o uso normal da CLI do GitHub. O Kilobat vê hosts e contagens de bytes, nunca o que foi enviado.
- O token npm foi roubado no GitHub Actions do Nx, nos runners do GitHub, e a segunda fase foi executada pelo atacante com tokens roubados. Nenhuma das duas passou pelo seu Mac.
- Instalações iniciadas por uma extensão de editor no VS Code não são atribuídas a um agente, portanto não teriam uma sessão de agente; no Cursor e no Windsurf, elas contam como pertencentes ao app.
- Ler arquivos, executar a busca de arquivos das CLIs de IA e editar
~/.zshrcnão são eventos de rede. - O registro de rede de agentes mantém 30 dias de histórico, portanto não pode dizer agora se isso foi executado no seu Mac em agosto de 2025.
Verifique seu Mac agora
Em cada projeto, verifique se há uma versão afetada do Nx instalada. Atualize se houver.
npm ls nxProcure os arquivos deixados pelo script. O macOS limpa
/tmpao reiniciar, portanto não encontrar nada prova muito pouco.ls -la /tmp/inventory.txt /tmp/inventory.txt.bakVerifique os arquivos de inicialização do shell em busca da linha de desligamento e apague-a se estiver presente.
grep -n "shutdown" ~/.zshrc ~/.bashrcNo registro de segurança do GitHub, procure um evento
repo.createcoms1ngularity-repositoryno nome: github.com/settings/security-log. O repositório em si pode já estar desativado.Se você foi afetado, revogue o acesso da CLI do GitHub em Settings › Applications › Authorized OAuth Apps, inicie sessão novamente com
gh auth logine substitua os tokens npm e todos os segredos em seus arquivos.enve no ambiente.Limpe o cache do npm para impedir que uma cópia antiga seja instalada novamente.
npm cache clean --forcePara o próximo caso: com o registro de rede de agentes do Kilobat ativo, veja o que cada instalação executada por um agente acessou. Observe se npm ou node se comunicam com api.github.com e se há sessões de agente que você não iniciou.
kilobat agent-log --all
Perguntas
As ferramentas de IA se voltaram contra seus usuários?
Não. O próprio script malicioso as iniciou com as flags que desativam suas solicitações de permissão e deu a elas suas próprias instruções. Essas mesmas flags são um motivo para ter cuidado ao executar agentes sem supervisão com permissões totais.
Por que o Kilobat não bloqueia uploads grandes para o GitHub?
Porque enviar código, releases e pacotes para o GitHub é um trabalho comum, e interrompê-lo quebraria git push. Em vez disso, o registro mostra o upload com seus bytes e processo para que você o veja.
Fontes
- Alerta de segurança nrwl/nx GHSA-cxm3-wv7p-598c: versões maliciosas do Nx e de alguns plugins de suporte foram publicadas
- Blog do Nx: S1ngularity, o que aconteceu, como respondemos e o que aprendemos
- StepSecurity: pacote do popular sistema de compilação Nx comprometido com malware que rouba dados
- Wiz: s1ngularity, ataque à cadeia de suprimentos vaza segredos no GitHub
- Snyk: uso de agentes de programação com IA como arma para malware no pacote malicioso do Nx
- Socket: pacotes npm do Nx comprometidos em ataque à cadeia de suprimentos que usa ferramentas CLI de IA como arma
Verificado em 1º de novembro de 2026.
Veja a que seus agentes e apps se conectam
O Kilobat é um app para a barra de menus do Mac que identifica o app, processo e agente por trás de cada conexão, mantém essas conexões longe de hosts reconhecidamente maliciosos e registra o que cada sessão de agente acessou.
brew install seifip/kilobat/kilobat