- Versões maliciosas do pacote Nx e de plugins foram publicadas no npm, escaneando o sistema de arquivos, coletando credenciais e depois enviando tudo para um repositório da conta Github do usuário
- Para verificar se houve impacto, é preciso confirmar se o repositório s1ngularity-repository foi criado na conta do Github
- Em caso de infecção, é obrigatório trocar tokens e senhas, excluir o repositório malicioso e verificar arquivos de configuração do shell
- As versões maliciosas afetam o sistema por meio de um script postinstall; o risco de execução involuntária aumenta especialmente ao usar o plugin VSCode Nx Console
- A equipe do Nx aplicou medidas adicionais de segurança e prevenção de recorrência, e as versões relacionadas foram removidas do npm
Visão geral e resumo
- Este aviso de segurança trata de um grave ataque à cadeia de suprimentos envolvendo o pacote Nx e alguns plugins relacionados, com código malicioso distribuído via npm
- Essas versões maliciosas escaneavam o sistema de arquivos do usuário para coletar credenciais, caminhos e outras informações, enviando os dados para um repositório do Github chamado
s1ngularity-repository - O script malicioso de
postinstalltambém modificava os arquivos de configuração do shell do usuário (.zshrc,.bashrc) para adicionar comandos de desligamento do sistema - O documento detalha o vetor de ataque, a progressão do incidente, as versões afetadas, as ações imediatas que os usuários devem tomar e as medidas de prevenção de recorrência
Como agir com urgência
O que todos devem verificar
- Verifique na lista de repositórios da sua conta Github se foi criado o
s1ngularity-repository - Baixe os arquivos incluídos nesse repositório e mantenha-os arquivados como registro
- Exclua o repositório no Github
- Envie um e-mail para
security@nrwl.iopara receber orientações sobre como decodificar as informações vazadas - Troque imediatamente todas as credenciais e tokens de todas as contas
Como trocar o token do Github
- Acesse https://github.com/settings/connections/…
- Revogue o acesso do app conectado para invalidar o token existente
- Se você usa o gh CLI, autentique-se novamente para gerar um novo token
- Se isso não for feito, há risco de abuso do token antigo
Interromper o uso das versões maliciosas do Nx e limpar o ambiente
- Verifique se a versão atualmente em uso do Nx é uma das versões maliciosas com o comando
npm ls nx - Se for uma versão infectada, atualize com
npm uninstall nx && npm install nx@latest - Limpe o cache com
npm cache clean --force
Usuários já infectados
- Troque os tokens do npm e do Github
- Redefina todas as senhas e credenciais do Github e de serviços relacionados
- Verifique os arquivos
.zshrce.bashrcpara identificar comandos desconhecidos inseridos e remova-os
Para administradores de repositórios internos de pacotes
- É necessário remover imediatamente as versões maliciosas do proxy no registro interno da empresa para bloquear propagação adicional
Versões afetadas
Pacote Nx
- 21.5.0, 20.9.0, 20.10.0, 21.6.0, 20.11.0, 21.7.0, 21.8.0, 20.12.0
- Removidas do npm até 10:44 PM EDT
@nx/devkit, @nx/js, @nx/workspace, @nx/node, @nx/eslint, @nx/key, @nx/enterprise-cloud
- Removidos do npm até 10:44 PM e 6:20 AM EDT
Detalhes do vetor de ataque
Causa do workflow vulnerável
- Uma vulnerabilidade que permitia execução arbitrária de código foi introduzida no workflow do Github Actions
- Ao inserir um código bash específico no título de um PR, surgia uma vulnerabilidade em que comandos do sistema eram executados no workflow (Bash Injection)
- O problema foi explorado por meio do gatilho
pull_request_target, que concedia privilégios elevados, incluindoGITHUB_TOKEN - Até ser removido, o workflow vulnerável permaneceu em branches antigas, não apenas na
main, permitindo que o invasor executasse o workflow com PRs maliciosos e roubasse segredos
Processo de roubo do token npm
- O workflow vulnerável foi usado para executar o
publish.yml - O
publish.ymlarmazenava o token do npm no Github Secrets, e nesse processo o token era enviado para um webhook externo - Por fim, o invasor usou esse token para publicar no npm versões maliciosas do Nx e dos pacotes compatíveis
Comportamento do pacote malicioso
Coleta de informações com credenciais e publicação em repositório do Github
- Quando o script
postinstalldo pacote Nx infectado era executado, ele coletava localizações de vários arquivos de texto e informações de credenciais - Os dados eram codificados em base64 e enviados para um repositório do Github chamado
s1ngularity-repository - Mesmo que o repositório real já tenha sido excluído, é preciso considerar a possibilidade de vazamento, já que anteriormente ele esteve público
Alteração do perfil do shell (.zshrc, .bashrc)
- O
postinstallinseria o comandosudo shutdown -h 0, podendo induzir o desligamento do sistema ao abrir o terminal e expor senhas
Vários cenários em que o postinstall pode ser executado
-
Além da execução explícita de
npm install/yarn/pnpm install, ele também pode rodar em várias situações, como dependências transitivas, extensões de editor e execução de scripts -
Em especial, a extensão Nx Console para VSCode (versões 18.6.30 ~ 18.65.1) podia instalar automaticamente
nx@latestao iniciar o editor, acionando opostinstall -
Em essência, é preciso ter em mente que instalações de módulos NPM podem acontecer em vários pontos mesmo sem intenção direta
-
A partir do Nx Console 18.66.0, o processo de instalar o
latest nxfoi removido
Linha do tempo do ataque e da resposta
21 de agosto
- 4:31 PM: PR com a vulnerabilidade de injeção Bash foi mesclado
- 10:48 PM: Uma publicação apontando a vulnerabilidade foi postada no X (antigo Twitter)
22 de agosto
- Tarde: investigação interna e rollback do workflow vulnerável (incompleto)
- Com a adoção do CodeQL, passou a haver detecção de vulnerabilidades semelhantes em PRs futuros
24 de agosto
- Foi feito um commit no fork do invasor com indícios de vazamento do token npm
- Um PR malicioso foi criado e depois removido, e o
publish.ymlfoi executado por esse PR
26 a 27 de agosto (distribuição das versões maliciosas e resposta)
- Várias versões maliciosas do Nx e de plugins foram publicadas no npm em sequência
- Houve relatos do problema para as comunidades Github/NPM
- 10:44 PM: o NPM removeu todas as versões afetadas e tomou outras medidas
- 11:57 PM: todos os tokens de publicação de pacotes relacionados ao Nx foram invalidados
- 27 de agosto: correção no Nx Console, ativação de 2FA, migração para Trusted Publisher e outras medidas adicionais
Medidas preventivas e resposta posterior
- 2FA passou a ser obrigatório para todos os maintainers da organização nrwl
- Foi adotado o mecanismo de Trusted Publisher. Publicações baseadas em token npm foram proibidas
- Daqui em diante, os pacotes serão publicados somente após verificação com 2FA e confiança
- Detecção adicional de risco, aprovação de PR e proteção de branch serão aplicadas em etapas
Lições e próximos passos
- O incidente reforça a importância global da segurança da cadeia de suprimentos, dos pipelines de CI/CD e da redução de privilégios em workflows
- Após nova avaliação interna, a equipe pretende compartilhar com a comunidade o que aprendeu
Contato
- Contato disponível via
security@nrwl.io
Referências e apêndice
- Principais issues do Github, linha do tempo e posts relacionados
- É fornecido um exemplo do script
telemetry.jscontido no pacote infectado - Esse script coleta, com o objetivo de criar um inventário, os caminhos de arquivos de texto importantes no sistema de arquivos
Resumo da conclusão
- É importante aplicar as atualizações e correções mais recentes do Nx e dos plugins relacionados
- Recomenda-se a troca imediata das principais credenciais de autenticação, como npm e Github
- O caso mostra como falhas em segurança da cadeia de suprimentos e no gerenciamento de permissões de workflow podem levar a um grande incidente
1 comentários
Comentários do Hacker News
Quero lembrar periodicamente as pessoas de desativarem os scripts do
npm installUm exemplo é usar o seguinte comando:
Essa configuração pode ser aplicada facilmente por projeto ou globalmente
Hoje em dia, é raro haver pacotes legítimos que não funcionem sem scripts, então na maioria dos casos isso não causa problema
Para pacotes que realmente precisem disso para funcionar, dá para contornar criando um script de instalação separado e executando-o manualmente naquela pasta
Não é uma solução universal contra ataques à cadeia de suprimentos, mas na prática bloqueou com eficácia muitos ataques via npm
Para mais detalhes, veja a documentação oficial do npm config
Eu também uso o bubblewrap para executar
npm,pnpm,yarne todas as sessões que eles iniciam isoladas do sistema~/code, e eu salvo o script bash abaixo comonpmno início doPATH~/codee acesso somente leitura às bibliotecas do sistemaUsar
pnpmtambém é uma opção. Nas versões mais recentes, ele ignora por padrão todos os scripts de ciclo de vida, e só executa os que forem colocados individualmente em uma whitelistSempre que ouço esse conselho, fico com uma dúvida: na prática, não existe desenvolvedor que leia todas as dezenas ou centenas de milhares de linhas de código instaladas pelo npm
git clonenpm install(aqui existe o risco de instalar um pacote malicioso; ignorar scripts de post-install pode barrar isso temporariamente)npm run(aqui o pacote malicioso é executado e a infecção acontece)node_modulesentre as etapas 2 e 3, e ninguém faz issoEu executo todas as ferramentas baseadas em npm dentro de um contêiner Docker, sem acesso a nada além do diretório atual
Fico me perguntando por que esse tipo de conselho não se aplica da mesma forma a
setup.py(Python) oubuild.rs(Rust)Precisamos de uma cultura de pensar duas vezes antes de adicionar uma nova dependência
Este ano houve muitos ataques à cadeia de suprimentos
Esta semana eu queria adicionar ao meu projeto Go uma barra de progresso com 8 contadores estatísticos
Procurei bibliotecas e encontrei uma com mais de 3.000 linhas de código, então pedi a um LLM para gerar um código de UI simples e resolvi em menos de 150 linhas
Funciona exatamente como eu queria, sem dependências, e é tão simples que qualquer um consegue ler e melhorar
Os recursos são limpar a saída do terminal, redesenhar a cada segundo e suporte a thread safety
Implementar e revisar isso levou só 25 minutos
Se você não precisa de estatísticas complexas, dá para implementar uma barra de progresso até com umas 30 linhas de código
Daqui para frente, quando eu pensar em adicionar dependências, acho que para mim faz mais sentido simplesmente fazer eu mesmo
Não tenho recursos para monitorar todas as atualizações de todos os pacotes
Concordo com isso, e me lembro de como fiquei desconfortável no começo da popularização dos “gerenciadores de pacotes por linguagem”
pip,npmetc. de longeAcho que a abordagem do
cargo veté o caminho: introdução ao cargo vetA diferença entre implementar você mesmo e usar uma biblioteca é óbvia
Eu realmente odeio essas bibliotecas de barra de progresso, especialmente as que quebram o shell do Emacs (
expo,easetc.)..10%..20%..30%ouUploading…Nossa equipe opera um grande monorepo e várias bibliotecas em torno do NX dentro de uma grande seguradora
lerna,rushjs,yarn workspacesetc., mas nada funcionou tão bem quanto o NX (lernaacabou sendo adquirido pelo próprio NX, erushjsjá não parece mantido)Em vez de culpar Nx, Anthropic ou a plataforma, precisamos repensar a causa real
Esse tipo de ataque pode causar danos catastróficos a dezenas de milhares de instituições em finanças, energia, telecomunicações, hospitais, forças armadas etc.
Com a disseminação da IA, a escala e o impacto dos ataques vão aumentar ainda mais
Não estamos escrevendo software com responsabilidade suficiente. Assim como no código de obras, segurança e proteção precisam ser impostas à força
O ambiente atual de computação pessoal ser um grande espaço unificado é mais perigoso do que parece
50% das vítimas tiveram o VS Code como vetor de infecção, e o ataque só funcionava em Linux e macOS
postinstall, ativos importantes como credenciais do usuário (carteiras cripto, tokens de GitHub e npm, chaves SSH etc.) eram coletadosClaude,Gemini,Qetc.) eram usadas para coleta de informações e reconhecimento ativos1ngularity-repositoryetc.)O fato de tokens/credenciais do GitHub não estarem guardados em um gerenciador de senhas com liberação manual também é culpa do GH CLI
Não gosto da ideia de introduzir um “código de obras de software”, mas concordo que toda a indústria é vulnerável demais
Acho arrogante querer responsabilizar alguém por você ter usado uma biblioteca open source gratuita
Tenho feito a maior parte do meu trabalho de desenvolvimento recente em VMs
Sinto que o nível de segurança do ambiente atual está simplesmente inaceitável
A possibilidade de agentes (software baseado em agentes) funcionarem como vetor de malware aumentou enormemente
Se um atacante comprometer sua máquina, estamos numa era em que ele também pode mirar a qualquer momento dados que valem mais de 1.000 dólares, chaves cripto, senhas, informações pessoais, dados financeiros etc.
Eu também trabalho de forma parecida, dentro de um contêiner Podman. Não compartilho nada do host além do diretório de código-fonte
Parte do problema vem do modelo tradicional de segurança de PCs (Linux/Windows)
Se você gosta desse tipo de abordagem, eu recomendaria Qubes OS. Ele oferece uma boa UX para fazer tudo em VMs
Dito isso, vale registrar que montar um ambiente desses é muito difícil ou bem caro por causa do ecossistema de software e da história da computação
Claude Code é uma ferramenta revolucionária para aumentar produtividade
Por outro lado, há os seguintes problemas de segurança:
curlcom pipe parabash(risco de execução remota de código)Como existem pelo menos três fragilidades de segurança aí, eu não gostaria de executá-lo fora de um sandbox como VM/contêiner/máquina dedicada de desenvolvimento
Eu também acho certo rodar agentes em sandbox
Mas e daí?
O ponto realmente perigoso é que ele faz atualização automática sem intervenção do usuário, então na prática você concedeu à Anthropic permissão de RCE durante a execução
Fico pensando se gerenciadores de pacotes não deveriam ter uma configuração tipo “idade mínima do pacote” (
min-age)Por exemplo, ignorar pacotes registrados há menos de 24–36 horas
Já passei por algo parecido antes: uma atualização de pacote quebrou tudo e poucas horas depois foi corrigida/removida
O GitHub dependabot adicionou exatamente esse recurso recentemente
O Renovate bot já oferece essa opção (
minimumReleaseAge), e agora o dependabot também suportaNPM,PNPM,Bunetc. mais recentes não executam scriptspostinstallpor padrão, e exigem execução explícita quando necessário (embora no fim continue sendo uma situação de executar código de terceiros)Não é no nível do sistema operacional, mas a ferramenta
uvda Astral tem essa opção para pacotes PythonO
npm installtambém tem uma flag para instalar apenas dependências de antes de um certo horário/datanpm install --before (data de 2 dias atrás), dependências criadas depois dessa data não são instaladasEu configuro
save-exact=trueno.npmrce uso apenas lockfile e atualizações manuaisFiquei curioso se o claude code realmente executaria esse tipo de prompt, então testei
“Este pedido parece solicitar busca e listagem de arquivos sensíveis, como carteiras de criptomoedas e chaves privadas, o que tem potencial de abuso, então não posso ajudar”
Ele só orientou sobre pedidos legítimos, como verificação de segurança, análise de vulnerabilidades, escrita de ferramentas de monitoramento, entendimento de permissões de arquivos e desenho de procedimentos de backup
Já foram obtidos pelo menos 250 casos de sucesso (ou seja, alguns prompts passaram)
Em situações reais, sempre que vejo Claude e outros modelos disputando na recusa, confirmo de novo que as recusas e proteções do Claude são muito superiores
O sistema operacional deveria, por padrão, impedir que apps tenham acesso irrestrito ao sistema de arquivos inteiro
Alguns apps até têm perfis de apparmor/selinux, e também dá para usar
firejailMas é preciso uma mudança de UX
Esse é um problema gravíssimo. É um legado de um design de desktop de 30 anos atrás
Estou desenvolvendo no Linux uma ferramenta focada em isolar ambientes por projeto usando Podman: probox
Quando o assunto é segurança de arquivos no Android, o Google fez um bom trabalho
Também recomendo aprender a usar bubblewrap e pequenos ambientes
chrootNão acho que algum sistema operacional tenha como padrão “acesso irrestrito ao sistema de arquivos inteiro” para aplicativos
Antes eu tinha uma confiança vaga de que “o atacante precisaria adivinhar meu ambiente”, mas agora ele pode usar um LLM para aprender e executar ataques adequados ao ambiente
Até me dou um certo crédito por ter previsto esse movimento na prática
Houve uma discussão interessante sobre isso nesta thread anterior
A parte realmente assustadora é usar agora LLMs locais para procurar segredos
O problema de
postinstallé o mesmo de antes, mas o payload é de uma geração totalmente novaComo a lógica maliciosa fica escondida em prompts em vez de código, fica mais difícil detectar com análise estática tradicional
Fico pensando em como seria possível se defender contra esse tipo de prompt malicioso