17 pontos por GN⁺ 2025-11-25 | 5 comentários | Compartilhar no WhatsApp
  • Mais de 1.000 componentes no registro NPM foram infectados em poucas horas com o mesmo método, e novas versões contendo código malicioso foram distribuídas
  • Os pacotes maliciosos se disfarçavam como script de instalação do runtime Bun, adicionando setup_bun.js e bun_environment.js ofuscado; ao executar, usavam o TruffleHog para roubar credenciais locais
  • Informações sensíveis coletadas, como tokens AWS/GCP/Azure, GitHub e NPM, eram enviadas para fora por meio de um runner do GitHub Actions chamado SHA1HULUD
  • O script malicioso executava npm publish automaticamente para realizar autorreplicação em forma de worm, resultando na infecção de mais de 27.000 repositórios GitHub
  • O caso é avaliado como mais um exemplo que volta a destacar a ameaça à segurança da cadeia de suprimentos em todo o ecossistema open source

Visão geral do ataque

  • Em 24 de novembro de 2025, a HelixGuard detectou que mais de 1.000 pacotes no registro NPM foram infectados com o mesmo método em poucas horas
    • As novas versões se disfarçavam como se estivessem adicionando o runtime Bun e incluíam o script preinstall: node setup_bun.js
    • O arquivo bun_environment.js, distribuído junto, continha código malicioso ofuscado e, ao ser executado, baixava e executava o TruffleHog
  • O TruffleHog escaneava e roubava do ambiente local tokens NPM, credenciais AWS/GCP/Azure e variáveis de ambiente
  • As informações roubadas eram exfiltradas por meio da criação do runner do GitHub Actions SHA1HULUD e de um repositório GitHub com a descrição Sha1-Hulud: The Second Coming.
  • A HelixGuard indica que esse ataque pode ter sido conduzido pelo mesmo agente do incidente “Shai-Hulud” ocorrido em setembro de 2025

Análise do funcionamento do código malicioso

  • Como exemplo, a análise do pacote @asyncapi/specs mostrou que a versão publicada no NPM estava infectada, enquanto o repositório original no GitHub permanecia seguro
  • O atacante modificou o package.json para adicionar setup_bun.js e configurar esse script para chamar bun_environment.js
  • O bun_environment.js é um arquivo JavaScript altamente ofuscado com mais de 10 MB, cujas funções principais são as seguintes
    • Coleta de credenciais de nuvem e tokens a partir de variáveis de ambiente
    • Varredura de segredos usando o TruffleHog
    • Exfiltração de dados por meio do GitHub Actions
  • Além disso, ele modificava o package.json para inserir o código de infecção e executava npm publish automaticamente para promover a propagação em forma de worm

Infecção no GitHub e exfiltração de dados

  • O script malicioso criava o arquivo .github/workflows/formatter_123456789.yml e registrava o runner SHA1HULUD
  • Esse workflow empacotava os segredos do repositório em um arquivo actionsSecrets.json com codificação dupla em Base64
  • Em seguida, criava um repositório GitHub com nome aleatório e descrição Sha1-Hulud: The Second Coming. para enviar os dados
  • A HelixGuard confirmou que mais de 27.000 repositórios GitHub foram infectados
  • Entre as informações secretas roubadas estavam credenciais de vários serviços, como AWS_ACCESS_KEY_ID, SLACK_WEBHOOK_URL, CODECOV_TOKEN e WEBFLOW_TOKEN

Lista de pacotes infectados

  • A HelixGuard relatou que centenas de pacotes NPM foram infectados
    • Entre eles estão pacotes de organizações importantes, como @asyncapi, @ensdomains, @posthog, @zapier, @postman e @voiceflow
    • Cada pacote teve várias versões infectadas, como @asyncapi/specs@6.8.2 e @postman/csv-parse@4.0.5
  • A maioria dos pacotes infectados se passava por projetos open source legítimos, com código malicioso inserido no processo de publicação automatizada

Implicações de segurança

  • Este ataque é um caso de infecção em larga escala do ecossistema open source por meio da exploração de fragilidades na segurança da cadeia de suprimentos
  • Ele evidencia a necessidade de reforçar a segurança em toda a infraestrutura de desenvolvimento, incluindo NPM, GitHub e credenciais de nuvem
  • A HelixGuard recomenda interromper imediatamente a instalação dos pacotes infectados e revogar imediatamente os tokens e credenciais relacionados

5 comentários

 
ahwjdekf 2025-11-27

O ecossistema de JS é mesmo um lixo caótico.

 
developerjhp 2025-11-25

Criei um script de scanner em tempo real.

No caminho do repositório suspeito,
digite npx sha1-hulud-scanner.

Código-fonte: https://github.com/developerjhp/sha1-hulud-scanner

 
GN⁺ 2025-11-25
Comentários do Hacker News
  • Uma dica: use PNPM em vez de NPM
    O PNPM 10.x bloqueia vários vetores de ataque
    1️⃣ Por padrão, ele não executa scripts de pós-instalação e exige aprovação manual
    2️⃣ Dá para configurar para só instalar depois de um certo tempo desde que uma nova release foi publicada (por exemplo, 4 dias)
    O NPM é instável demais em ambientes de CLI de produção
    É melhor restringir chaves de publicação ao menor privilégio possível, vinculá-las apenas a pacotes específicos e limitar o IP aos runners de CI/CD
    Não deixe chaves de publicação na máquina local; se necessário, considere OIDC Trusted Publisher ou acesso baseado em token

    • O NPM parece o resultado de dívida técnica acumulada demais
      Só o lockfile já foi tentado umas cinco vezes e ainda não está perfeito
      Pela estrutura e pelo histórico de commits, dá para ver que a equipe está se esforçando para melhorar, mas a sensação é de que começaram de um buraco fundo demais
      Ele ainda não detecta EOF prematuro durante transferências de arquivo e deixa arquivos incompletos no cache, então em conexões lentas se perde muito tempo com falhas de atualização
    • Eu prefiro a abordagem de segredos dinâmicos do HashiCorp Vault / OpenBao
      No começo é mais complexo, mas permite gerenciar segredos como leases
      Dá para criar um lease a cada build de CI e descartá-lo automaticamente no fim, com suporte a TTL e rotação automática
      Assim, você evita esconder credenciais de longo prazo e emite tokens de curta duração apenas no momento do build
      O lado positivo desses ataques é que eles realmente estimulam discussões de segurança dentro das empresas
    • Basta usar npm ci
      Ele instala apenas as versões especificadas no package-lock.json, então reduz o risco de ataques causados por atualizações automáticas
      O importante é ter o hábito de fazer apenas atualizações intencionais
    • No ecossistema Python, dá para obter uma proteção parecida com a opção pip install --only-binary=:all:
      Ela bloqueia completamente distribuições em código-fonte e instala apenas wheels
      Mas isso pode impor restrições de versão
      No uv, a opção --exclude-newer pode imitar o recurso de “período mínimo desde o lançamento” do PNPM
    • Vi recentemente um texto sobre “dependency cooldown” e concordei bastante
      Eu fixo todas as dependências e reviso manualmente os alertas do dependabot
      Ainda fico em dúvida se isso é exagero ou uma prática correta
  • Tem um texto especialmente relevante hoje: “We should all be using dependency cooldowns”
    Atualizações automáticas de dependências podem ser mais perigosas do que vulnerabilidades de um dia
    É muito mais difícil reverter um pacote infectado que já se espalhou por milhares de lockfiles

    • Acho melhor atualizar só quando realmente for necessário
      Se está funcionando bem, não há motivo para mexer
    • Mas mesmo assim alguém precisa corrigir os bugs, e se todo mundo usar cooldown talvez no fim tudo fique no mesmo lugar
    • No uv do Python, dá para obter um efeito parecido com o comando uv lock --exclude-newer $(date --iso -d "24 hours ago")
      A discussão relacionada está na issue #14992
    • Também dá para fazer isso facilmente com npm-check-updates
      O comando npx npm-check-updates -c 7 permite configurar um cooldown de 7 dias
      Veja a documentação do npm-check-updates
    • Não concordo com essa lógica
      Cooldowns podem aumentar o tempo de propagação de vulnerabilidades 0-day
      Se todos usarem o mesmo cooldown, isso só atrasa a descoberta
  • Sou cofundador da PostHog
    Fomos uma das vítimas deste ataque
    As versões infectadas foram posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
    Já trocamos todas as chaves e senhas e publicamos novas versões
    Estamos investigando a causa e vamos publicar atualizações em status.posthog.com

    • Recomendo configurar um alerta para quando uma nova release de pacote não estiver associada a uma execução de CI/CD
    • Fico curioso se o JS infectado chegou a afetar usuários reais
      Se algum site distribuiu a versão comprometida, gostaria de saber se houve impacto para os visitantes
    • Se a causa ainda não é conhecida, talvez o ataque ainda esteja se espalhando
    • Se a versão mais recente também puder ser infectada, por que as pessoas deveriam confiar desta vez?
    • Ainda bem que a atualização aparece melhor aqui do que no anúncio no Twitter. Espero que a recuperação corra bem
  • Pergunta séria: faz sentido começar um projeto novo em Node?
    Estou fazendo um frontend SaaS com Astro e fico inseguro toda vez que atualizo dependências
    A falta de segurança no ecossistema npm parece grave demais

    • O problema não é Node nem JS, e sim o modelo de empacotamento
      Ecossistemas como Rust, que dependem de inúmeros subpacotes, vão passar por algo parecido em algum momento
      Talvez a ausência de gerenciador de pacotes, como em C, C++ e Odin, seja até uma escolha mais sensata do ponto de vista de segurança
    • Acho que o problema é mais do próprio npm do que do Node
      Ultimamente confio mais no JSR do Deno
      Pacotes baseados em JSR também são publicados no npm, e também existem pacotes exclusivos do Deno
      Por exemplo, o Lume me impressionou como um SSG lento, porém estável
    • Não é um problema exclusivo do Node
      O npm só é o repositório de maior valor para atacantes porque é o maior
      Isso perfeitamente poderia acontecer também no RubyGems ou no Cargo
    • Achar que devemos evitar Node é exagero
      Só é o ecossistema mais usado, então os ataques se concentram nele
      Basta gerenciar as dependências com cuidado e não atualizar todo dia
    • Nós desenvolvemos nossa plataforma de análise de segurança de produto em PHP
      Uma vantagem é não precisar de mais de 100 dependências para renderizar páginas
      Veja o link do projeto
  • Hoje em dia faço todo o desenvolvimento apenas dentro de contêineres Podman
    Código que eu não li sempre roda em ambiente isolado
    Não é perfeito, mas considero isso um hábito mínimo de segurança

    • A maioria das pessoas nunca tem problema em 99,99% dos casos, então perde a noção do risco
      Segurança costuma ser uma área delegada a especialistas, então na prática é difícil mudar isso
    • As árvores de dependência do npm são profundas demais; fico curioso sobre como esse isolamento por contêiner funciona nesses casos
    • Gostaria de saber de forma concreta como lidar com um pacote npm como o SDK do PostHog dentro de um contêiner
    • O Podman é mais seguro que o Docker, e se necessário também vale considerar isolamento adicional com algo como QEMU
    • Eu vou além: entro por SSH com outro usuário local e desenvolvo com tmux
  • Há 12 anos o NPM chegou a ficar completamente fora do ar uma vez
    Na época era apenas um projeto open source, mas hoje pertence à Microsoft
    Sendo uma das maiores empresas do mundo, não deveria conseguir resolver esse tipo de problema?
    Mas no fim parece que pouca coisa mudou

    • A MS nem o Windows consegue administrar direito
      Tudo que não dá dinheiro com licença enterprise acaba deixado de lado
      Por isso o Windows 11 parece mais uma peça de marketing
  • Estamos atualmente monitorando a atividade do ataque e atualizando a lista de pacotes infectados no blog da Wiz
    Estamos fazendo engenharia reversa do payload malicioso e devemos compartilhar os resultados dentro de algumas horas

  • A conversa “Talk to a human” da PostHog na verdade dava respostas de robô, o que foi frustrante
    Nem o link de suporte emergencial era bem indicado
    Então quero perguntar diretamente — quais versões devem ser evitadas?

    • Sou cofundador. Já publicamos isso no tópico principal e em status.posthog.com
      As versões infectadas foram posthog-node 4.18.1, 5.13.3, 5.11.3 / posthog-js 1.297.3 / posthog-react-native 4.11.1 / posthog-docusaurus 2.0.6
      Atualizar para a versão mais recente é seguro
    • Também recebi a mesma lista de versões no canal do Slack
  • Fico me perguntando por que esse tipo de caos com pacotes sempre acontece no ecossistema Node
    Não entendo por que essa comunidade acredita que hooks de instalação complexos e atualizações automáticas são boa engenharia
    Dá para entender por que o criador do Node já foi embora

    • Node é o novo PHP
      Ecossistema enorme, centrado em desenvolvedores iniciantes, pouca consciência de segurança e dependência de bibliotecas até para funcionalidades pequenas
    • Um ecossistema sério deveria ter mantenedores de pacotes
      Como no Debian, deveria haver validadores confiáveis, mas a comunidade JS rejeita isso como gatekeeping
      Por isso esse tipo de situação continua se repetindo
    • Sentir superioridade diminuindo os outros dura pouco
      Com essa atitude, nada vai mudar
  • Um pouco fora do assunto, mas fiquei curioso sobre quem é a HelixGuard
    O site é ruim e quase não há informação
    Dizem que o cliente é uma exchange de criptomoedas, o que parece meio suspeito

 
laeyoung 2025-11-25

2️⃣ É possível configurar para só instalar depois de passar um certo período (por exemplo, 4 dias) desde que a nova versão foi publicada

Que recurso ótimo. Até o Google às vezes publica no NPM versões com bug ou que nem funcionam, então já aconteceu de eu ficar confuso achando que o problema era um bug meu.