Alerta: módulo peacenotwar sabota desenvolvedores npm no pacote node-ipc em protesto contra a invasão da Ucrânia
16 de março de 2022
0 minutos de leituraEm 15 de março de 2022, usuários do popular framework JavaScript de front-end Vue.js começaram a enfrentar o que só pode ser descrito como um ataque à cadeia de suprimentos que afetou o ecossistema npm. Isso aconteceu porque as dependências aninhadas node-ipc e peacenotwar foram sabotadas pelo mantenedor do pacote node-ipc como forma de protesto.
Este incidente de segurança envolve atos destrutivos de corrupção de arquivos em disco por parte de um mantenedor e suas tentativas de ocultar e reapresentar essa sabotagem deliberada de diferentes formas. Embora seja um ataque motivado por protesto, ele destaca um problema mais amplo que afeta a cadeia de suprimentos de software: as dependências transitivas do seu código podem ter um enorme impacto na sua segurança.
A Snyk está acompanhando os incidentes de segurança descritos neste artigo por meio dos seguintes CVEs: CVE-2022-23812 para node-ipc e SNYK-JS-PEACENOTWAR-2426724 para os módulos npm peacenotwar e oneday-test. Se você já usa a Snyk para proteger software de código aberto e a cadeia de suprimentos, receberá notificações, alertas e pull requests automatizados gerados pelas ferramentas para manter você protegido e informado sobre o caso. Continue lendo para saber mais sobre os detalhes desse ataque à cadeia de suprimentos.
Eventos anteriores que levaram ao abuso do pacote npm node-ipc
A história começou em 8 de março de 2022, às 18h (GMT+2), quando o mantenedor do npm RIAEvangelist (Brandon Nozaki Miller) escreveu o código-fonte e publicou um pacote npm chamado peacenotwar, que, segundo a descrição do módulo:
Até ontem (15 de março), esse módulo praticamente não tinha downloads. Isso mudou quando seu mantenedor no npm adicionou o módulo como dependência de outro pacote popular, o node-ipc, que por si só é uma dependência bastante usada por muitos desenvolvedores JavaScript do ecossistema.

Um dos projetos do ecossistema JavaScript que usa esse pacote é a ferramenta de linha de comando do Vue.js, a Vue.js CLI, também conhecida como pacote npm @vue/cli. A árvore de dependências aninhadas a seguir mostra exatamente como o node-ipc chega ao pacote npm Vue.js CLI e reforça a necessidade de avaliar as dependências aninhadas como um risco integrado:
A versão “estável” mais recente do pacote npm node-ipc (versão 9.2.2) inclui o peacenotwar e, curiosamente, também inclui o infame pacote npm colors com um intervalo de dependência curinga *. Se você ainda não conhece a história do pacote npm colors e do faker, que foram intencionalmente manipulados e corrompidos pelo mantenedor Marak, recomendo que leia sobre o caso para conhecer outra perspectiva sobre a segurança da cadeia de suprimentos de código aberto.
Cronologia dos acontecimentos
Versões anteriores do node-ipc, como a 10.1.0 (lançada há seis meses) e as versões anteriores à 10.0.0 (lançada há nove meses), receberam atualizações e melhorias legítimas. No entanto…
7 de março
Na semana passada, a versão 10.1.1 foi publicada com alterações claras no código que levantaram suspeitas de atividade maliciosa e possível abuso do código-fonte e do comportamento do pacote. Vamos analisar as diferenças entre as versões 10.1.0 e 10.1.1:
O módulo CommonJS compatível com Node.js node-ipc.cjs é bastante extenso, com mais de 1.000 linhas de código. A presença de chamadas HTTPS de saída para locais remotos e de dados codificados em Base64 já é motivo suficiente para alertar sobre possíveis irregularidades e serve de base para IoCs (indicadores de comprometimento).
O código adicionado ao node-ipc@10.1.1 configura um temporizador. Assim, em intervalos aleatórios predefinidos, sempre que um código relacionado ao node-ipc é chamado, uma função também é executada para, aparentemente, realizar operações no sistema de arquivos.
Vamos analisar mais de perto os valores codificados em Base64 dos argumentos passados à função que executa operações no sistema de arquivos. No diff acima:
Em seguida, todos esses valores são passados à função do temporizador, por exemplo:
Os valores das strings codificadas em Base64 acima são:
n2é definido como:./o2é definido como:../ré definido como:../../fé definido como:/
Quando passados à função do temporizador, esses valores são usados na linha de código a seguir como fontes de entrada de arquivos, para apagar o conteúdo dos arquivos e substituí-lo por um emoji de coração (representado pela linha de diff + const c = Buffer.from("4p2k77iP", "base64");)
Nesse momento, ocorrerá um abuso evidente e um incidente crítico de segurança da cadeia de suprimentos em qualquer sistema que execute esse pacote npm, caso ele esteja em uma localização geográfica correspondente à Rússia ou à Belarus.

O conteúdo atualizado do arquivo README para node-ipc@10.1.1não menciona esse novo comportamento. Em vez disso, inclui um convite para patrocinar RIAEvangelist e um exemplo de como usar as versões ES6 e CommonJS do node-ipc nas versões 10 e posteriores.
Cerca de dez horas depois, foi lançada a versão node-ipc@10.1.2, praticamente sem mudanças, exceto pelo aumento do número da versão. Talvez a intenção fosse acionar atualizações automatizadas de dependências. Veja o diff completo do Git entre as duas versões:
8 de março
Cerca de cinco horas depois, em 8 de março, foi lançada uma nova versão: node-ipc@10.1.3, que aparentemente removeu todos os indícios do payload destrutivo mencionado. A análise do diff do Git entre as duas versões confirma:
Suspeitamos que isso tenha sido removido da linha de versões 10.x após uma conversa iniciada pela issue do GitHub que relatou esse comportamento, na qual o mantenedor afirma ter publicado esse payload como parte de uma nova versão principal da biblioteca:

Assim, podemos resumir que as versões vulneráveis do node-ipc, node-ipc@10.1.1 e node-ipc@10.1.2, ficaram disponíveis no registro npmjs por menos de 24 horas. Ainda assim, devido ao alto número de downloads por desenvolvedores e sistemas de build, elas certamente afetaram alguns usuários, como confirmamos em relatos publicados em repositórios públicos:

No entanto, as versões vulneráveis 10.1.1 e 10.1.2 não estão mais disponíveis no registro npmjs e foram marcadas como deprecated, seja pelo mantenedor, seja pela equipe do npmjs. Podemos confirmar isso pelo aviso a seguir no site do npmjs:

Em 8 de março, às 19h25 (GMT+2), menos de quatro horas após a publicação do node-ipc@10.1.3, que reverteu o payload destrutivo, uma nova versão principal, node-ipc@11.0.0, foi lançada no registro npmjs. O que mudou?
A nova versão principal node-ipc@11.0.0 passou a incluir:
Uma dependência do módulo
peacenotwarSempre que a funcionalidade do módulo
node-ipcé chamada, ele imprime no STDOUT uma mensagem do módulopeacenotware também cria um arquivo na área de trabalho do usuário com conteúdo relacionado à situação de guerra entre Rússia e Ucrânia.O README da versão 11.0.0 informa explicitamente o uso do
peacenotwarcomo parte desse módulo na seguinte observação:***as of v11*** this module uses the [peacenotwar](https://github.com/RIAEvangelist/peacenotwar) module.
O que levou o pacote npmpeacenotwar a ser incluído nas versões principais do node-ipc, afetando milhões de desenvolvedores?
15 de março
Ontem, 15 de março, às 18h49 e às 19h40 (GMT+2), duas novas versões npm importantes e de grande impacto foram publicadas para o node-ipc. A mais significativa delas é uma nova versão de correção, node-ipc@9.2.2, por ser a versão estável mais recente do node-ipc e ser usada por muitos projetos do ecossistema, incluindo a Vue.js CLI @vue/cli, mencionada anteriormente.
Veja a seguir as mudanças adicionadas ao node-ipc@9.2.2:
Adiciona ao conteúdo do pacote alguns exemplos de código-fonte.
Adiciona
peacenotwarcomo dependência e o executa quando qualquer dependência que importa onode-ipcchama esse módulo.Também adiciona explicitamente uma dependência de
colors@*, que inclui código-fonte intencionalmente vulnerável, publicado por outro mantenedor.Nesta nova versão secundária, a licença foi alterada de MIT para DBAD. Nota do editor: a licençaDBADcontém linguagem grosseira.
Por volta do mesmo horário, foi lançada uma nova versão secundária: node-ipc@11.1.0, que atualiza a dependência peacenotwar para uma nova versão, mas remove as mensagens console.log() registradas no STDOUT. Podemos confirmar isso no log de diff do Git a seguir, entre os dois pacotes npm do node-ipc:
Segurança da cadeia de suprimentos diante da reputação dos mantenedores
Mesmo que algumas pessoas considerem o ato deliberado e perigoso do mantenedor RIAEvangelist uma forma legítima de protesto, como isso afetará sua reputação e sua posição futura na comunidade de desenvolvedores? Esse mantenedor voltaria a receber confiança para não repetir esse tipo de ação em projetos dos quais participa — ou até mesmo adotar medidas mais agressivas?
Atualmente, RIAEvangelist mantém mais de 40 outros pacotes npm, que somam centenas de milhões de downloads. Veja alguns dos módulos que mantém e o número de downloads semanais no registro npmjs:
Módulo npm | Downloads semanais |
|---|---|
node-ipc — Um módulo Node.js para comunicação entre processos (IPC) local e remota, redes neurais e suporte a machine learning. | 1,055,386 |
js-queue — Fila JS simples com execução automática para Node e navegadores. | 1,042,512 |
easy-stack — Pilha JS simples com execução automática para Node e navegadores. | 1,001,945 |
js-message — Protocolo normalizado de mensagens e eventos para objetos JS e JSON, para node.js, JavaScript puro, react.js, componentes, ações, stores e dispatchers. | 1,001,943 |
event-pubsub — Eventos e EventEmitters extensíveis, superleves e rápidos para ES6+ no Node e no navegador. Fácil para desenvolvedores de todos os níveis; use exatamente o mesmo código no Node e no navegador. Sem complicações, apenas eventos em alta velocidade! | 996,076 |
node-cmd — Interface simples de linha de comando, terminal e shell que permite executar comandos no estilo CLI ou bash como se você estivesse no terminal. | 41,083 |
A equipe de Pesquisa de Segurança da Snyk não encontrou indícios de abuso intencional semelhante em outros pacotes desse mantenedor, mas continua atenta às atualizações publicadas no ecossistema npmjs.
Como reduzir os riscos do problema do node-ipc
Como há preocupações de que futuras atualizações de código possam colocar usuários em risco, recomendamos evitar completamente o pacote npm node-ipc. Se esse pacote npm estiver incluído no seu projeto como parte do aplicativo que você está desenvolvendo, recomendamos usar o recurso de substituição do gerenciador de pacotes npm para excluir de vez as versões sabotadas e fixar a dependência transitiva em uma versão conhecidamente segura.
Se você usa o npm como gerenciador de pacotes, pode adicionar o seguinte ao arquivo package.json para permitir explicitamente apenas versões seguras do node-ipc:
Vítimas conhecidas e de grande visibilidade do incidente do node-ipc
Projeto Vue.js vulnerável ao protestware do node-ipc
A Vue.js CLI dependia da faixa de versões 9.x do node-ipc e estava vulnerável à versão 9.2.2, que adicionou o módulo peacenotwar, responsável por criar o arquivo WITH-LOVE-FROM-AMERICA.txt na área de trabalho do usuário. A vulnerabilidade na @vue/cli já foi corrigida. Atualize para as versões mais recentes da @vue/cli — 4.5.16 ou posterior, ou 5.0.3 ou posterior — usando o gerenciador de pacotes de sua preferência:
Mecanismo de jogos Unity vulnerável ao protestware do node-ipc
Usuários relataram que o projeto do mecanismo de jogos Unity estava distribuindo seu software junto com node-ipc@9.2.2. Isso alarmou usuários que, para sua surpresa, encontraram um novo arquivo na área de trabalho. A equipe do Unity correu para lançar uma versão de correção 3.1.1 em 16 de março para minimizar o problema.
Resumo
A Snyk está ao lado da Ucrânia e tomou medidas proativas para apoiar o povo ucraniano durante a crise em curso, com doações e serviços gratuitos para desenvolvedores do mundo todo, além de encerrar suas atividades comerciais na Rússia e em Belarus. Dito isso, abusos intencionais como esse prejudicam a comunidade global de código aberto e exigem que sinalizemos as versões afetadas de node-ipc como vulnerabilidades de segurança.
Por isso, a equipe de segurança da Snyk publicou CVE-2022-23812 e SNYK-JS-PEACENOTWAR-2426724 para alertar sobre a vulnerabilidade de segurança e acompanhá-la nas versões de node-ipc intencionalmente vulneráveis. O plano gratuito da Snyk também já inclui essa nova vulnerabilidade, permitindo que desenvolvedores analisem, monitorem e implantem automaticamente correções de segurança por meio de pull requests.
Ainda assim, o impacto dos incidentes de segurança na cadeia de suprimentos continua mostrando a necessidade de gerenciar adequadamente os riscos associados às dependências de código aberto e agir com rapidez. Além disso, a complexidade das dependências aninhadas — como no ecossistema JavaScript do npmjs — voltou a evidenciar o efeito multiplicador que elas têm nos principais projetos do ecossistema.
Há apenas dois meses, abordamos as consequências generalizadas de um incidente de segurança semelhante, em que um mantenedor de código aberto desativou os pacotes npm ‘colors’ e ‘faker’, mostrando como mantenedores podem sabotar intencionalmente bibliotecas de código aberto.
Desenvolver habilidades para gerenciar dependências de software em grande escala está se tornando cada vez mais importante. Também é essencial que você, como desenvolvedor, siga as práticas recomendadas de segurança do npm e conheça os riscos e incidentes de segurança, como os pontos cegos de segurança dos arquivos de lock do npm, que podem permitir a injeção de módulos maliciosos.
Saiba mais sobre segurança da cadeia de suprimentos nestes artigos:
