Aikido

Confusão npx: pacotes que se esqueceram de reivindicar o seu próprio nome

Charlie EriksenCharlie Eriksen
|
#
#
#

Em julho de 2025, eu estava a criar um protótipo para um novo projeto e decidi experimentar o MikroORM. A documentação dizia para executar npx mikro-orm-esm para migrações. E foi o que fiz.

npm ERR! código E404
npm ERR! 404 Não encontrado - GET https://registry.npmjs.org/mikro-orm-esm

O pacote não existe, que estranho! Então me ocorreu: e se alguém tivesse registado isso? Eu teria visto:

É necessário instalar os seguintes pacotes:
mikro-orm-esm@1.0.0
Pode prosseguir? (y)

Eu teria simplesmente batido y. Todos fazem isso. E nada nessa mensagem indica se você está prestes a instalar um malware ou uma ferramenta legítima.

Os documentos apontavam para um pacote inexistente. Quantas outras referências phantom estão por aí? Quantas já foram reivindicadas por atacantes? Eu precisava saber.

Então, comecei a pesquisar. Escrevi scripts para verificar o npm em busca de pacotes referenciados em READMEe guiões, mas nunca chegou a publicar. Cruzou milhares de referências npx Invocação. Encontrei dezenas. Reivindiquei 14 delas antes que alguém o fizesse. Então aconteceu a Singularidade, e a pesquisa foi arquivada.

Seis meses depois, lembrei-me da minha pesquisa graças à comunidade que investigava assuntos semelhantes. Finalmente verifiquei o número de downloads: 121 539 downloads!

As pessoas estavam a executar esses comandos inexistentes milhares de vezes por semana. Durante meses. Enquanto os pacotes ficavam lá, a recolher dados. 

Seis meses de dados

Os downloads não permaneceram estáveis. Eles cresceram. Começaram lentamente no final de julho. O pico recente atingiu 4.236 downloads em um único dia (16 de janeiro de 2026).

121.539 downloads em 7 meses
128 pacotes phantom , julho de 2025 a janeiro de 2026
121,539
Total de downloads
3,903
Média semanal
4,236
Dia de pico (16 de janeiro)
4K 3K 2K 1K 🎄 Molho festivo Pico: 4.236 Jul Agosto Set Out Nov Dezembro Janeiro
O volume semanal de downloads cresceu de forma constante entre julho de 2025 e janeiro de 2026.
  • Total: 121.539 downloads em 128 pacotes
  • Média semanal: 3.903
  • Dia de pico: 4.236 downloads (16 de janeiro de 2026)

Nota rápida sobre ruído: sempre que publica uma nova versão de um pacote, ele recebe automaticamente 60 a 100 downloads de scanners de segurança e espelhos. Esse é o ruído básico por lançamento. Pacotes com várias versões acumulam ruído rapidamente. Qualquer coisa consistentemente acima desse limite é uso real.

Reparou na queda no final de dezembro? Feriados. Até mesmo os downloads phantom tiram férias no Natal.

Os Três Grandes

Três pacotes representam 79% de todos os downloads:

  • openapi-generator-cli: 48.356 downloads (pacote real: @openapitools/openapi-generator-cli)
  • cucumber-js: 32.110 downloads (pacote real: @cucumber/cucumber)
  • depcruise: 15.637 downloads (pacote real: navegador de dependências)
Os três grandes: 79% de todo o tráfego
Três phantom representam 96.103 do total de 121.539 downloads
openapi-generator-cli → atual: @openapitools/openapi-generator-cli
48,356
23 referências npm650 resultados no GitHub3.994 nos últimos 7 dias
cucumber-js → real: @cucumber/cucumber
32,110
28 referências npm856 resultados no GitHub
depcruise → real: dependência-cruiser
15,637
27 referências npm836 resultados no GitHub

openapi-generator-cli teve 3.994 downloads apenas nos últimos 7 dias. Isso significa que quase 4.000 vezes alguém tentou executar um comando que não existe. Em uma semana.

A Cauda Longa

Os restantes pacotes com downloads significativos:

  • jsdoc2md: 4.641 downloads
  • grpc_tools_node_protoc: 4.518 downloads
  • vue-demi-switch: 1.166 downloads
  • guia de estilo: 805 downloads
  • mikro-orm-esm: 314 downloads
  • pvbase64: 142 downloads
  • cromwell: 106 downloads
A Cauda Longa
Pacotes restantes com contagens de downloads notáveis (excluindo os Três Grandes)
jsdoc2md
4,641
grpc_tools_node_protoc
4,518
vue-demi-switch
1,166
guia de estilo
805
mikro-orm-esm
314
pvbase64
142
cromwell
106
📊 Limite de ruído: cada lançamento de versão gera 60 a 100 downloads do scanner. Pacotes com menos de 100 no total (mostrados a cinzento) são provavelmente todos ruído. Tudo acima disso representa máquinas reais, ambientes reais, credenciais reais.
Mais de 1000 downloads100-1K downloadsNo limiar de ruído

Lembra-se daquela base de referência de 60 a 100 downloads por versão? Um pacote com três versões poderia ter de 180 a 300 downloads de puro ruído. fathym com um total de 83 downloads, provavelmente é tudo ruído. Mas mikro-orm-esm Com 314? Mesmo considerando as várias versões, são tentativas reais.

guia de estilo com 805 downloads significa centenas de execuções reais. Pode ser CI/CD a atingi-lo repetidamente. Podem ser dezenas de programadores diferentes. De qualquer forma, é o uso real de um pacote que não deveria existir.

Como descobrimos isso

Operamos um espelho completo do registo npm na Aikido. Analisado todos os package.json e README em todo o registo. Extraído npx comandos. Referenciados em relação ao que está realmente registado. Também pesquisámos a pesquisa de código do GitHub para ver com que frequência esses phantom aparecem na prática, em documentação, configurações de CI, scripts, em qualquer lugar onde os programadores possam referenciá-los.

Três pontos de dados para cada pacote:

  • Referências no registo: Quantos pacotes npm mencionam este comando no seu package.json ou README
  • Resultados do GitHub: Quantos ficheiros de código ou repositórios referenciam este comando no GitHub
  • Downloads: Quantas vezes as pessoas realmente tentaram executá-lo

Reivindicámos 14 em julho de 2025. Quando retomei a pesquisa em janeiro, expandimos a nossa análise e encontramos muitos mais. Neste momento, reivindicámos 128 pacotes no total.

Discriminação completa do pacote
Referências npm, resultados de pesquisa de código GitHub e downloads para todos os pacotes reivindicados
Referências npmResultados do GitHubTransferências
🔴 Principais vetores de ataque (mais de 10 mil downloads)
Pacote Referências GitHub Transferências
openapi-generator-cli 23 650 48,356
cucumber-js 28 856 32,110
depcruise 27 836 15,637
🟡 Vetores de ataque significativos (1 mil a 10 mil downloads)
Pacote Referências GitHub Transferências
jsdoc2md 92 155 4,641
grpc_tools_node_protoc 83 226 4,518
vue-demi-switch 70 80 1,166
Risco moderado + Limiar de ruído
Pacote Referências GitHub Transferências
guia de estilo ALTA EXPOSIÇÃO 246 286 805
mikro-orm-esm SOMENTE DOCUMENTOS 0 80 314
pvbase64 18 70 142
cromwell 31 23 106
git-scripts-pre-push BAIXA CONVERSÃO 126 133 93
fathym BAIXA CONVERSÃO 119 9 83
aofl, flatjs-forge 42, 30 30, 2 99, 91
Conclusão principal: referências npm elevadas nem sempre significam downloads elevados. O styleguidist tem 246 referências, mas 805 downloads, enquanto o mikro-orm-esm tem 0 referências, mas 314 downloads apenas a partir da documentação.

Alguns padrões dignos de nota:

Principais vetores de ataque (mais de 10 mil downloads): openapi-generator-cli, cucumber-js, e depcruise todos mostram uma forte correlação entre referências npm, menções no GitHub e downloads reais. Isso seria devastador nas mãos de um invasor.

Alta exposição, baixa conversão: guia de estilo tem 246 referências npm e 286 resultados no GitHub, mas apenas 805 downloads. git-scripts-pré-push tem 126 referências, mas apenas 93 downloads. Visibilidade nem sempre é sinónimo de execução.

Vetores apenas para documentação: mikro-orm-esm não tem nenhuma referência no pacote npm, mas tem 80 resultados no GitHub e 314 downloads. Isso prova que a documentação por si só pode gerar centenas de instalações, mesmo sem nenhuma referência no ecossistema npm.

Por que isso é perigoso

O ataque é simples.

Um invasor regista o pacote. Adiciona um postinstall script que extrai variáveis de ambiente: tokens npm, credenciais de nuvem, chaves API, tudo o que estiver disponível. Em seguida, aguarda.

No pico, isso representa potencialmente cerca de 4.000 máquinas comprometidas por semana. Estações de trabalho de programadores. Servidores CI. Ambientes de compilação. Muitos deles provavelmente estão a funcionar com credenciais em variáveis de ambiente. Não é necessário phishing. Não há comprometimento da cadeia de suprimentos de pacotes existentes. Basta reivindicar o nome e esperar que o npx traga as vítimas até si.

Quando alguém executa o comando, vê:

É necessário instalar os seguintes pacotes:
openapi-generator-cli@1.0.0
Pode prosseguir? (y)

A mensagem não mostra quem a publicou. Não mostra quando. Não mostra se é o que você está procurando. Você pode ver essa mensagem regularmente para ferramentas legítimas. A memória muscular assume o controle, porque somos humanos. Você digita y, como todos os outros fazem. É isso. Esse é todo o ataque.

Fechámos 128 lacunas em várias rondas. Detetámos os piores casos. Mas ainda há milhares de outros.

Uma nota sobre as proteções do npm

O npm possui proteção contra typosquatting. Quando tentámos reivindicar determinados nomes, o npm rejeitou-os com erros de similaridade. Nomes como rsbuild, vuedoc, napi, t-ci estavam muito próximos dos pacotes existentes. Isso é bom. Significa que o npm está a bloquear ativamente tentativas óbvias de apropriação indevida.

Mas esses phantom não são erros de digitação. São nomes que nunca foram registrados. A verificação de similaridade do npm não os detecta porque não há nada com que eles sejam "semelhantes".

O que deve fazer

Use npx --no-install

npx --no-install seu-comando

Isso força o npx a usar apenas binários locais. Sem recurso ao registo. Se não estiver instalado, falha. É isso que você quer.

Instale as ferramentas CLI explicitamente. Não confie em npx para buscá-los:

{
  "devDependencies": {
    "@openapitools/openapi-generator-cli": "^2.7.0"
  }
}

Verifique antes de executar. A documentação diz para executar npx alguma coisa? Verifique primeiro se o pacote realmente existe. Verifique se é o pacote certo. Especialmente em CI/CD.

Reivindique o seu namespace. Se mantém uma ferramenta CLI, registe os aliases e erros ortográficos óbvios. É um seguro barato contra alguém fazer isso de forma maliciosa.

Como saber se está afetado

Se for Aikido , verifique o seu feed central e filtre as questões relacionadas com malware. Quaisquer vulnerabilidades phantom aparecerão como uma questão crítica 100/100 no feed. Aikido os seus repositórios todas as noites, mas recomendamos que também seja realizada uma verificação completa.

Se ainda não é Aikido , crie uma conta gratuita e conecte os seus repositórios. A nossa cobertura proprietária contra malware está incluída no plano gratuito (não é necessário cartão de crédito).

Para proteção futura, considere usar Aikido (código aberto), um wrapper seguro para npm, npx, yarn e pnpm. O SafeChain fica nos seus fluxos de trabalho atuais, interceptando comandos de instalação de pacotes e verificando os pacotes em relação Aikido ( Threat Intelligence nossa Threat Intelligence de código aberto) antes que eles cheguem à sua máquina. Pare as ameaças na porta.

A matemática

121.539 downloads em sete meses. Média de 3.903 por semana. Pico de 4.236 em um único dia. Total de 128 pacotes reclamados (14 em julho, o restante em janeiro).

O ecossistema npm tem milhões de pacotes. Os programadores executam comandos npx milhares de vezes por dia. A diferença entre «padrão conveniente» e «execução arbitrária de código» é um nome de pacote não reivindicado.

4.7/5

Proteja seu software agora

Comece Gratuitamente
Não é necessário cc
Agendar uma demonstração
Seus dados não serão compartilhados · Acesso somente leitura · Não é necessário cartão de crédito

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.