Melhores práticas de segurança do npm para instalações seguras

Os patches do php2shell (CVE-2026-109618 e CVE-2026-109619) para o PHP em fim de vida (EOL) já estão disponíveis. Como as respostas do atendimento de vendas estão mais demoradas do que o normal devido à alta demanda, a maneira mais rápida de obter os pacotes corrigidos é adquirir o ELS para Runtimes on-line (abre em uma nova aba). Leia as perguntas frequentes sobre os patches

Vá direto para um resumo gerado por IA desta postagem do blog

  • Resuma esta postagem com o Perplexity
  • Resuma esta postagem com o Gemini

A cada comando `npm install` é um ato de confiança. O mesmo ecossistema de pacotes que agiliza o desenvolvimento em JavaScript também é um dos principais vetores para ataques à cadeia de suprimentos. Ao executar um comando de instalação, você está trazendo uma árvore extensa de dependências, muitas das quais são obscuras e ocultas.

npm install é seguro na maioria das vezes. Esse “na maioria das vezes” envolve muito trabalho. A instalação não é apenas um download, é uma execução, e os scripts do ciclo de vida das dependências são executados com as permissões que o ambiente de instalação já possui. Em um laptop de desenvolvedor ou em um executador de CI, isso geralmente é suficiente. O código é baixado, descompactado e executado antes que alguém o tenha revisado. Tudo o que se segue reflete o npm v12, o pnpm 11 e o Yarn 4.10 em agosto de 2026, pois as configurações padrão nessa área têm mudado rapidamente.

A armadilha do typosquatting

Esse ataque ocorre quando um invasor publica um pacote que contém um erro de digitação. O erro pode ser um simples erro ortográfico no nome do pacote ou uma tática de formatação totalmente diferente. Ele parece quase idêntico a pacotes populares e reproduz a mesma funcionalidade.

  • Manipulação de caracteres: Troca lodash por lodahs, ou usar homógrafos (por exemplo, substituir o ‘l’ pelo ‘I’).
  • Variações de formatação: Usando truques com hífens (cross-env vs. crossenv) ou pluralização (color vs. colors).
  • Confusão entre namespace e escopo: Criação de pacotes maliciosos com escopo restrito que imitam bibliotecas oficiais.

Esses pacotes podem executar código arbitrário durante o processo de instalação e extraem todos os tipos de credenciais — desde chaves de API e variáveis de ambiente até credenciais da AWS, etc. Isso pode ocorrer com extrema rapidez, antes mesmo que um desenvolvedor tenha a chance de revisar o código.

Como funcionam os ataques de confusão de dependências

Esse ataque se aproveita de organizações que utilizam uma configuração híbrida, ou seja, um repositório interno em conjunto com o repositório público do npm.

Os ataques de “confusão de dependências” ocorrem quando uma empresa possui um pacote interno e um invasor publica outro com o mesmo nome no registro público. Normalmente, o invasor publica esse pacote com um número de versão superior ao do pacote interno. Se o seu ambiente de compilação conseguir resolver esse nome em ambos os registros, ele poderá baixar o pacote público do invasor por engano. É nesse pacote que se encontra o código malicioso.

O fato de isso acontecer ou não depende da configuração do seu registro, escopo, proxy e arquivo de bloqueio. As configurações afetadas são aquelas que ninguém auditou.

A maneira de mitigar esse risco é usar pacotes com escopo definido e tornar o roteamento determinístico. Mapeie explicitamente cada escopo privado para o seu registro privado em .npmrce certifique-se de que nada na sua cadeia de proxy recorra silenciosamente ao escopo público. Reivindique o escopo correspondente em npmjs.com acrescenta uma segunda camada de proteção, pois um invasor não pode publicar sob um escopo que você já possui. Se você instalou alguma coisa nos últimos anos, sabe o que é um pacote com escopo. Um pacote com escopo tem um formato semelhante a este: @my-org/cool-package. O primeiro caractere é o símbolo @, seguido pelo seu nome ou da sua organização e pelo nome do pacote que você está instalando.

Sem essas salvaguardas, a definição de escopo por si só não impedirá completamente o ataque. Um escopo, por si só, é uma convenção de nomenclatura, não um controle. Garantir que sua plataforma de CI/CD esteja configurada corretamente também ajuda a mitigar o risco.

O que acontece quando a conta de um mantenedor é invadida

Tanto o typosquatting quanto a confusão de dependências exigem que você instale algo que não pretendia instalar. A versão mais sofisticada pula essa etapa. O invasor assume o controle de um pacote no qual você já confia, que já foi revisado e já está fixado.

Este é o vetor que está causando mais danos no momento. Uma campanha de phishing contra mantenedores do npm, em setembro de 2025, gerou o worm Shai-Hulud, que roubou tokens de nuvem e os utilizou para se espalhar para outras contas. Em 4 de agosto de 2026, um invasor conseguiu acessar a conta no GitHub do mantenedor responsável pelo keyv, uma biblioteca com bem mais de 100 milhões de downloads semanais, e publicou versões que roubavam credenciais em todo o keyv, cacheable, flat-cache, cache-de-entradas-de-arquivoe outros nesse cluster. Os rastreadores contabilizaram centenas de nomes de pacotes afetados e mais de mil versões afetadas em um dia.

Aqui está a parte que deveria te preocupar. A versão foi lançada por meio do próprio fluxo de trabalho do GitHub Actions do mantenedor; portanto, ela trazia uma proveniência válida baseada em OIDC e um hash de integridade válido. Ambos descreviam exatamente o artefato corrompido que o fluxo de trabalho legítimo havia produzido. A proveniência estabelece onde e como um pacote foi compilado. Ela não diz nada sobre quem detinha as chaves.

Foram as ferramentas comportamentais e os controles de versão que detectaram esse caso, e não as verificações criptográficas. É importante ter a proveniência, mas ela não é o objetivo final.

Por que as dependências transitivas não são auditadas

Uma dependência direta, mesmo que tenha sido auditada, pode acarretar inúmeras dependências transitivas que você não viu e das quais não tem conhecimento. Essas dependências ocultas podem estar a uma profundidade de 5 a 10 ou mais camadas na árvore de dependências.

A maioria das dependências está localizada nas camadas mais profundas da árvore do projeto, onde raramente são verificadas manualmente, criando uma “caverna escura” totalmente exposta a invasores. Essa falta de visibilidade é um dos principais vetores para ataques à cadeia de suprimentos. Eles ocorrem quando agentes mal-intencionados se infiltram em pacotes ou os injetam por completo, muitas vezes passando despercebidos durante a instalação — um risco que até mesmo algumas ferramentas de geração de código baseadas em IA não conseguem resolver, conforme observado na minha post no blog sobre o Dockerfile.

Enquanto o npm ls é uma ferramenta útil para visualizar árvores completas de dependências, ela não verifica se há vulnerabilidades ou comportamentos suspeitos. É por isso que as ferramentas de Análise de Composição de Software (SCA) são importantes para identificar problemas profundamente aninhados na pilha.

Ferramenta É bom em Vou sentir falta
Dependabot CVEs conhecidos em sua árvore de código-fonte, PRs automatizados para atualização de versão Pacotes maliciosos totalmente novos, já que ainda não existe nenhum CVE
Soquete Sinais comportamentais, novos scripts de instalação, acesso inesperado à rede ou ao sistema de arquivos Não foi concebido inicialmente como um banco de dados CVE
Snyk Cobertura de CVEs, além de verificações da cadeia de suprimentos e das licenças É preciso ajustar antes que a saída deixe de ser ruído

O Dependabot é a opção básica e de baixo esforço se seus repositórios estiverem no GitHub. Só não o confunda com a detecção de pacotes maliciosos, pois um pacote publicado há uma hora ainda não tem um CVE com o qual possa ser comparado.

Quão malicioso pré-instalação e pós-instalação executam código

pré-instalar e pós-instalação ganchos em package.json executam o código automaticamente assim que um pacote é baixado e descompactado, antes que o desenvolvedor analise o conteúdo do pacote.

Esses scripts têm como alvo ativos de alto valor, como sistemas bancários, servidores de compilação etc. O melhor do melhor, por assim dizer. Eles extraem credenciais essenciais, como arquivos .env , tokens da AWS e chaves SSH — sobre as quais somos constantemente lembrados NÃO enviar para o controle de versão.

Alguns scripts realizam verificações de ambiente para detectar sandboxes ou sistemas fortemente monitorados antes de executar sua carga maliciosa, visando primeiro os ambientes menos protegidos.

Esse ainda é o mecanismo de distribuição preferido. Todas as versões infectadas da campanha de agosto de 2026 continham um dropper .

No entanto, as configurações padrão finalmente mudaram. O pnpm deixou de executar scripts do ciclo de vida das dependências por padrão na v10, e o npm v12, lançado em 8 de julho de 2026, adotou a mesma abordagem, gerenciada por meio de npm approve-scripts. Um script não aprovado é ignorado com um aviso; portanto, defina strict-allow-scripts se você preferir que a CI falhe. No npm 11 ou versões anteriores, o sinalizador faz isso por você:

bash

npm install --ignore-scripts

É importante saber que nada disso afeta a execução no momento da importação. Um pacote comprometido cujo código de nível superior seja executado quando seu aplicativo chamar require() ignora completamente os controles do script de instalação.

Por que a idade da embalagem é um indicador de segurança

A maioria desses ataques é detectada, geralmente em questão de horas, e não de semanas. O problema é que seu CI já baixou a versão corrompida durante essas horas.

Uma idade mínima de lançamento reduz essa janela sem exigir que ninguém faça nenhuma auditoria. Todos os principais gerenciadores de pacotes já oferecem esse recurso. O pnpm 11 passa a minimumReleaseAge ativado por padrão em 1.440 minutos, enquanto o Yarn 4.10 define como padrão npmMinimalAgeGate em três dias, e o npm possui min-release-age a partir da v11.10, mas deixa essa configuração desativada; portanto, você mesmo deve defini-la. Preste atenção às unidades, pois o npm conta em dias e o pnpm, em minutos.

# .npmrc

min-release-age=7

A maioria dos profissionais opta por um prazo de três a sete dias. Isso não resolve o problema de um pacote que já era malicioso desde o início, nem de um que permanece inativo além do seu limite.

O npx requer a mesma consideração. Quando ele busca algo novo, seu arquivo de bloqueio não determina qual versão será escolhida; portanto, fixe o que você invoca com npx [email protected].

Como instalar pacotes do npm com segurança

  • Certifique-se de fazer o commit dos arquivos de bloqueio e use npm ci para compilações determinísticas e confiáveis em ambientes de CI. O arquivo de bloqueio, juntamente com npm ci é o que realmente define sua árvore resolvida, incluindo dependências transitivas.
  • Defina as versões exatas no package.json removendo os símbolos de prefixo (^, ~) nos casos em que você deseja controlar o momento da atualização das dependências diretas. Isso proporciona previsibilidade, mas não segurança, já que não afeta a árvore transitiva.
  • Faça com que o gerenciador de pacotes bloqueie scripts de dependência por padrão. Esse já é o comportamento no pnpm 10 e versões posteriores, bem como no npm v12, e isso é –ignore-scripts em versões anteriores.
  • Faça auditorias regulares em seus pacotes e utilize ferramentas de SCA, como Dependabot, Socket ou Snyk, para detectar anomalias em sua árvore de dependências.
  • Ative uma idade mínima de liberação de três a sete dias.
  • Ative a autenticação multifatorial (MFA) para todas as contas com permissão de publicação e mantenha os tokens de publicação restritos e de curta duração.

Bloquear scripts tem um custo real, portanto, decida com cuidado. Módulos nativos e ferramentas de automação do navegador exigem etapas de instalação, e precisa, bcrypt, Prisma, Playwright e Cypress costumam ser as primeiras a serem afetadas. Na CI, bloqueie por padrão, aprove apenas o que for necessário e execute essas compilações em um ambiente que não contenha suas credenciais de produção. Em um laptop, aprove o único pacote que apresentar falha, em vez de desativar a proteção para tudo. Fique atento a falhas silenciosas em ambos os casos, pois uma compilação nativa bloqueada pode ser concluída sem erros e só vir à tona mais tarde como um módulo ausente em tempo de execução.

Considerações finais sobre a segurança da cadeia de suprimentos do npm

A segurança da cadeia de suprimentos de software nunca é um requisito operacional que se resolve de uma vez por todas. A prática da segurança é contínua e deve estar sempre em primeiro plano. Três aspectos que costumam ser deixados de lado até que a situação fique crítica são o desempenho, a acessibilidade e — você adivinhou — a segurança. Manter-se atualizado sobre ferramentas e técnicas que ajudam a garantir sua segurança faz parte do trabalho de um desenvolvedor. Tenha em mente medidas práticas de defesa e sempre coloque a segurança em primeiro plano no momento do lançamento.

 

Resumo
Melhores práticas de segurança do npm para instalações seguras
Nome do artigo
Melhores práticas de segurança do npm para instalações seguras
Descrição
Cada comando `npm install` executa código. Saiba como funcionam o typosquatting, a confusão de dependências e o sequestro de contas de mantenedores, e como instalar pacotes
Autor
Nome da editora
TuxCare
Logotipo da editora

Junte-se a mais de 4.500 profissionais de Linux e código aberto!

2 vezes por mês. Sem spam.

Índice
Obtenha as respostas sobre segurança de código aberto de que você precisa

Junte-se a mais de 4.500 profissionais de Linux e código aberto!

2 vezes por mês. Sem spam.