1 pontos por GN⁺ 2025-09-09 | 2 comentários | Compartilhar no WhatsApp
  • Em 8 de setembro, foi detectada a inserção de malware em pacotes npm populares
  • Ao todo, 18 pacotes foram afetados, com mais de 2 bilhões de downloads por semana no mundo todo
  • O invasor incluiu código que intercepta secretamente operações de criptomoedas e Web3 no navegador dos visitantes de sites e redireciona aprovações e fluxos de fundos nas carteiras para contas controladas pelo atacante
  • Foi confirmado que código JavaScript ofuscado foi adicionado aos principais arquivos dos pacotes (index.js)
  • O incidente começou ao mesmo tempo que as atualizações dos pacotes-alvo, e a comunidade está respondendo no momento

Visão geral do incidente

  • Em 8 de setembro, às 13:16 UTC, o feed de monitoramento de segurança da Aikido detectou o upload para o npm de vários pacotes contendo malware
  • Esses pacotes são extremamente populares no npm e registram mais de 2 bilhões de downloads por semana

Método e conteúdo do ataque

  • Após a atualização maliciosa, foi confirmada uma estrutura em que malware em JavaScript é executado secretamente nos navegadores dos visitantes de sites que usam esses pacotes
    • O objetivo desse código é monitorar atividades de criptomoedas e Web3, adulterar interações com carteiras e alterar sem autorização os endereços de destino dos pagamentos
    • Sem qualquer mudança visível na tela, os fundos e permissões de aprovação do usuário podem ser enviados para endereços de criptomoeda definidos pelo atacante

Análise detalhada do código malicioso

  • Em casos representativos, como is-arrayish, o arquivo index.js foi adulterado para inserir JavaScript complexo e ofuscado
  • No código, a interface window.ethereum é usada para verificar informações da conta da carteira e passar por um procedimento de checagem das condições de ativação do código malicioso
  • Internamente, há vários endereços de criptomoedas (Bitcoin, Ethereum etc.) e lógica de funções, implementando a substituição de endereços de carteira e detalhes de transações pelos endereços do atacante
  • Isso cria o risco de que os ativos em criptomoedas de usuários reais sejam exfiltrados e transferidos sem autorização, sem que percebam

Situação atual e resposta da comunidade

  • As versões maliciosas dos pacotes problemáticos estão sendo rapidamente removidas dos principais repositórios npm
  • Na comunidade de TI e open source, estão em andamento de forma ativa orientações para suspender o uso e atualizar os pacotes relacionados, além de atividades de detecção de infecções adicionais e medidas de resposta
  • Este incidente de invasão está aumentando fortemente a conscientização sobre segurança da cadeia de suprimentos de pacotes, detecção de código ofuscado e proteção de extensões de navegador Web3

2 comentários

 
crawler 2025-09-09

> 8 de setembro de 2023,

A data saiu errada por alucinação. Não é sobre 2023, é de agora.
Parece que notícias de invasões no npm aparecem com bastante frequência. Parece haver um problema.

 
GN⁺ 2025-09-09
Comentários do Hacker News
  • Sim, fui comprometido. Estou realmente envergonhado e peço desculpas a todos. Para mais detalhes, vejam aqui e aqui. Publiquei a lista de pacotes afetados. Este ataque parece ter sido direcionado. Vou continuar atualizando até acabar o prazo de edição do comentário. O pacote Chalk foi recuperado, mas os demais ainda seguem comprometidos (dia 8, 17:50 CEST). A NPM ainda não deu nenhum retorno. Minha conta da NPM está inacessível, e a recuperação de senha também não funciona. No momento, tudo que posso fazer é esperar. O e-mail do suporte veio de npmjs dot help e parecia muito convincente. Não é desculpa, mas era uma manhã cansativa, eu queria resolver pelo menos uma tarefa e acabei clicando no link em vez de acessar diretamente o site oficial como faço normalmente (acho que por estar no celular). Este ataque afetou apenas a NPM, e vou continuar postando atualizações no link /debug-js. Mais uma vez, sinto muito

    • A forma rápida e transparente como você está reagindo numa situação tão estressante é realmente exemplar. A gente acha que nunca vai cair em phishing, mas eu acrescentaria algumas dicas: 1) nunca faça login por links de e-mail. Phishing e e-mails legítimos são difíceis demais de distinguir, então a única forma de não cair é simplesmente nunca tentar. 2) usar chaves de segurança U2F/Webauthn como segundo fator é quase uma proteção perfeita contra phishing. TOTP não oferece isso. No fim, qualquer pessoa pode errar quando está cansada ou ocupada. Desta vez, infelizmente, foi você o alvo. Mais uma vez, admiro muito a forma como está lidando com isso

    • Por indicação do sindresorhus, dá para verificar se há malware na árvore de dependências com o comando abaixo: rg -u --max-columns=80 _0x112fa8 (precisa do ripgrep, instala com brew install rg). Veja também o comentário original

    • Na faculdade, certa vez fui vítima de phishing quando estava bêbado (faz muito tempo). Qualquer pessoa pode virar vítima. Mas me surpreende a lentidão da resposta da NPM. Isso provavelmente só favorece ainda mais os atacantes

    • A Socket detectou isso imediatamente. Eles falam sobre o caso neste post do blog. A situação é lamentável, mas é bom ver que o ecossistema open source reagiu muito rápido. Casos assim mostram de novo por que a varredura de pacotes é importante

    • Obrigado por avisar tão rápido. Enviei um e-mail para a porkbun pedindo o bloqueio do domínio

  • Há uma parte sutil desse payload malicioso que não recebeu atenção suficiente. Em vez de simplesmente substituir endereços de carteira de forma aleatória, ele calcula a distância de Levenshtein entre o endereço correto e cada endereço da lista dele, e escolhe a carteira do atacante mais parecida. Ou seja, foi projetado para driblar o hábito comum de segurança de só conferir rapidamente o começo e o fim do endereço. Há uma análise detalhada que deofuscou todo o payload e examinou até essa funcionalidade específica. Cuidem-se

    • Fiquei confuso com uma parte do texto, porque eu entendia que o package-lock.json fixa uma versão específica de forma "exata". O package.json pode definir algo como "versão x ou superior", mas no lockfile ficam gravadas diretamente a versão resolvida de cada dependência e a URL do tarball. Com lockfile, em CI, os pacotes não deveriam ser atualizados automaticamente, então estou me perguntando se entendi errado como funcionam os lockfiles do npm/yarn/pnpm. Vejam também esta citação da documentação oficial da npm

    • Acho que, se o hash fosse exibido com cada caractere em uma cor diferente (cor de frente/fundo definidas por um esquema derivado do hash e do índice), seria muito mais fácil distinguir visualmente hashes parecidos feitos para enganar

    • Queria saber se há alguma informação ligando essa técnica a algum grupo específico de hackers

    • Esse código de ataque é engenhoso, mas, na prática, a web já luta contra ataques de endereços parecidos há décadas, e isso não passa de uma versão mais dinâmica da mesma coisa. Não concordo com esse entusiasmo exagerado. Sinceramente, a análise toda me parece até texto gerado por IA, então não me soa como uma avaliação particularmente cuidadosa

  • Fiz um comentário parecido 12 dias atrás quando aconteceu a mesma coisa com a Nx. Isso não é falha de uma pessoa só, é falha de toda a indústria. Ataques de supply chain têm impacto enorme e, na minha opinião, já deveriam ser um problema resolvido. Somos desenvolvedores de software; isso seria evitável se medidas padrão de segurança como assinatura de código, assinatura de artefatos, detecção de comportamento anômalo em contas, 2FA etc. fossem adotadas de forma ampla. O fato de as plataformas de empacotamento ainda não fazerem isso não é limitação técnica, é falta de obrigação. Com o avanço da IA e o sucesso repetido desses ataques no mundo real, isso vai piorar. Já passou da hora de tornar padrões fortes de segurança algo obrigatório

    • Essas medidas de segurança têm trade-offs. Por exemplo, aplicar mecanismos heurísticos ou baseados em prova pode excluir bastante automação e também usuários comuns. 2FA por SMS é fraco, e e-mail também tem alto risco de phishing. TOTP só ajuda quando usado como padrão aberto, e ainda assim não elimina phishing. Autenticação baseada em hardware é a única realmente eficaz, mas tem a limitação de ser difícil de aplicar em plataformas de grande escala

    • Não é tão simples quanto dizer "se seguirmos os padrões de segurança, tudo se resolve". Mesmo com medidas perfeitas, erro humano ainda compromete o sistema inteiro. Não existe sistema totalmente seguro. O avanço da IA está tornando e-mails de phishing quase indistinguíveis dos reais, mas, por outro lado, a própria IA também pode melhorar a detecção desses ataques. No fim, vamos ter que nos defender com IA mesmo

    • Antes havia muitos ataques voltados ao Windows, mas hoje há muito mais desenvolvedores de JavaScript e Python. Esses ataques vão ficar cada vez piores

  • Acho que a NPM também tem parte da culpa. Vários fornecedores externos de segurança e startups detectam rapidamente esse tipo de atividade maliciosa, então é difícil entender por que a NPM, que tem visibilidade em tempo real de todos os pacotes e eventos de segurança, continua tão impotente repetidamente. Está quase no nível de parecer que finge não ver

    • A NPM agora é da GitHub, ou seja, da Microsoft. Parece que eles estão ocupados demais enfiando IA generativa tipo Copilot em tudo quanto é aplicativo

    • Pacotes mantidos por várias pessoas deveriam pelo menos ter a opção de exigir aprovação de outro mantenedor antes de permitir um publish

    • O mesmo atacante injetou de uma vez payloads ofuscados (e muito suspeitos) em mais de 22 pacotes que estavam inativos havia muito tempo e publicou tudo simultaneamente. Acho quase impossível exigir que a NPM detecte isso em tempo real. Eu já publiquei apps/extensões em outras plataformas e às vezes é normal esperar dias ou semanas. O que me surpreende é que, mesmo com a Microsoft e o GitHub vendendo todo tipo de solução de segurança, a NPM ainda dá poucos sinais de investimento real no serviço

    • Também não acho que a NPM tenha grande motivo para mudar. Ela é fonte de distribuição de malware há mais de 10 anos, mas ninguém para de usar, então isso não afeta o negócio

    • Uma das causas é a expansão exagerada dos package managers. Sempre detestei depender até de pacotes minúsculos. Também odeio a experiência de puxar versões mais novas aleatoriamente e quebrar o ambiente. Não é só a npm; package manager em geral me irrita do mesmo jeito

  • Neste ponto, quem digita senha manualmente em sites que não batem com o domínio oficial, sem usar gerenciador de senhas, não deveria estar fazendo nada importante na internet

    • Um gerenciador de senhas/autofill do navegador teria avisado sobre esse domínio falsificado e teria evitado a divergência entre npmjs.help e o domínio oficial nesse phishing da NPM

    • Isso é verdade, mas várias vezes já vi apps oficiais e sites oficiais usarem domínios completamente diferentes. O pior caso é quando o app mobile e a web usam domínios distintos. Não sei quem acha isso uma boa ideia

  • Sempre que algo assim acontece, eu não entendo por que os registries de pacotes não exigem assinatura criptográfica de todos os pacotes. Claro, se a assinatura for automatizada no CI/CD e esse ambiente também for comprometido, ainda dá para burlar, mas isso já bloquearia a maioria dos casos. Em troca, o desenvolvedor teria que passar por etapas extras, como baixar artefatos manualmente, assinar e fazer upload

    • Um registry de verdade já faz isso como o Debian. A npm é amadora, por isso em muitos ambientes corporativos ela é proibida

    • O modelo que eu mais gosto é verificação posterior. Faz o upload automatizado no CI/CD e depois exige um clique humano na web para a publicação de fato acontecer. Assim você reduz o atrito no processo de release, mas ainda mantém uma aprovação humana final

    • Mas aí continua existindo o problema difícil de "em qual chave de assinatura confiar". Qualquer pessoa que roube o 2FA pode subir uma nova chave e assinar com ela, então talvez fosse preciso algo como atrasar o registro de novas chaves quando houver atividade suspeita na conta

  • Cheguei à conclusão de que é muito melhor evitar o npm registry. Acho melhor buscar pacotes diretamente dos repositórios (git). O npm registry é um dos principais canais para ataques de supply chain, e ainda existe o problema de que o código-fonte e o código distribuído ficam totalmente separados. O npm publish pode enviar qualquer código que estiver localmente, então um agente malicioso consegue inserir malware com facilidade

    • Existe um recurso de verificação de autenticidade quando se publica do GitHub builds para a npm, mas ainda parece possível publicar a partir de outros ambientes, então não entendo claramente como isso funciona

    • Como desenvolvedor C, é muito estranho ver que coisas como minimizar dependências, usar bibliotecas single-header e fazer vendoring foram tratadas como práticas ultrapassadas, e agora todo mundo está redescobrindo que elas eram úteis o tempo todo

    • O recurso recente de provenance da npm resolve esse problema. Também é bem fácil de configurar e ajuda a prevenir ataques como esse. Fico feliz de ver pacotes grandes adotando isso em sequência

    • Fico curioso se esse modelo também é usado em ambiente de CI. Quero dizer, se em vez de npm install no servidor vocês passam a usar git clone

    • "Buscar pacotes direto do repositório git" parece bom na teoria, mas na prática a npm tem muitos bugs e vários deles afetam a instalação de dependências via git. Como mencionei nesta issue, por causa de problemas na etapa de build isso não funcionava direito até 2020, e ainda há problemas quando se faz npm install globalmente. Mesmo que o script prepack esteja documentado pela npm, ele na prática não funciona para dependências baseadas em git. A equipe do compilador TypeScript também teve que usar um workaround esquisito por causa desse bug, e há um código de workaround e também o bug. Outro problema é que, mesmo quando o prepack falha, o npm não propaga o exit code, então o npm install termina como se nada tivesse acontecido, mas quebrado. Vendo isso, acho que a npm precisa urgentemente de uma governança operacional de verdade ou então ser substituída por um package manager novo

  • Para quem está fora do ecossistema npm, é impressionante ver o quanto esses pacotes são usados até para coisas triviais

    • O motivo é que a biblioteca padrão é fraca demais, e até funcionalidades básicas acabam exigindo pacotes externos. Se você tentar fazer tudo por conta própria, até implementações triviais viram bastante trabalho

    • Falando com base em 15 anos de experiência, muitos desenvolvedores JavaScript profissionais praticamente não sabem programar de verdade. Não é uma questão de inteligência, mas de formação e cultura. Existe um medo extremo de escrever código próprio, e isso leva as pessoas a dependerem de bibliotecas externas até para detalhes mínimos. Em projetos hobby, curiosamente isso costuma ser menos comum e o código às vezes é até mais robusto. Se quiser ver isso na prática, peça para colegas de empresa construírem algo sem um framework grande

    • Importar módulos pequenos e triviais tem o objetivo de evitar mandar código desnecessário para o cliente. Bibliotecas mais abrangentes dão uma DX mais limpa, mas acabam incluindo código que você não queria (mesmo com tree-shaking, que não resolve tudo)

    • Desde o caso do leftpad esse debate continua. Talvez seja porque a biblioteca padrão do JS é pequena demais

    • Em revisão de código, um PR que só adiciona uma linha de import de um módulo que parece "trusted" costuma parecer muito mais fácil de aprovar do que uma grande alteração de código. Na prática não é mais seguro, mas quando a pessoa está cansada isso parece mais plausível

  • No caso da nx eu já dei a mesma opinião antes: package managers deveriam ter um período de carência obrigatório para pacotes novos, por exemplo 24 horas. A maioria desses ataques é detectada e bloqueada logo após o release, então, se os usuários não instalassem automaticamente a versão mais recente nesse intervalo, o dano real poderia ser bem menor

  • Consigo imaginar a dor e o estresse pelo que o autor deve ter passado. Deve ser muito pesado ter que continuar explicando tudo por causa de um único erro. Isso também mostra como o ecossistema open source depende fortemente de pacotes mantidos por uma pessoa só. Precisamos aceitar que qualquer um pode ser hackeado por um erro. Do ponto de vista técnico, numa era em que IA está sendo usada em tudo, parece necessário que deno/node/bun exibam alertas para código suspeito, que haja algo como publicações @verified baseadas em autenticação no estilo Debian para aumentar a confiança, e uma mudança cultural para usar versões verificadas em vez de sempre puxar a mais recente. O autor também é humano, e todos nós deveríamos tratá-lo com gentileza. Quando a situação estiver resolvida, eu também gostaria de ver uma análise técnica mais detalhada ou um postmortem