npm 12 bloqueia scripts de instalação por padrão: como migrar sem liberar tudo

O npm 12 chegou à versão estável em 8 de julho de 2026 com uma mudança importante no contrato do npm install: uma dependência já não recebe permissão implícita para executar código na instalação. Scripts de ciclo de vida, builds nativos acionados por node-gyp e dependências obtidas fora do registry agora exigem decisões explícitas.

A mudança reduz uma porta conhecida para ataques à cadeia de dependências, mas também pode quebrar builds legítimos. O caminho seguro não é reativar tudo. É descobrir quais pacotes dependem dessa execução, entender por quê e registrar uma política pequena o bastante para continuar auditável.

O que deixou de acontecer automaticamente

No npm 12, allowScripts vem desligado para dependências. Isso bloqueia preinstall, install e postinstall que não foram aprovados. O bloqueio inclui o node-gyp rebuild implícito de um pacote com binding.gyp, mesmo que não exista uma linha de install em seu package.json.

Duas origens também mudaram de padrão. --allow-git e --allow-remote passam a none, então referências Git e tarballs por URL não são resolvidos sem autorização. Isso não torna um pacote do registry confiável; apenas fecha caminhos que davam a uma árvore de dependências mais formas de buscar e executar conteúdo fora do fluxo esperado.

A primeira instalação pode parecer bem-sucedida e ainda estar incompleta

Por padrão, um script não revisado é bloqueado com aviso. A instalação pode terminar, mas uma dependência nativa pode ficar sem binário compilado ou uma ferramenta pode não gerar os artefatos de que precisa. Por isso a validação precisa ir além do código de saída do npm install.

  • rode a instalação em ambiente limpo, sem node_modules reaproveitado;
  • leia a lista de scripts pendentes, em vez de procurar apenas erros fatais;
  • execute build, testes e um fluxo que realmente carregue dependências nativas;
  • compare Linux, macOS e Windows quando o projeto distribui binários por plataforma;
  • ative strict-allow-scripts no CI para transformar dependências não revisadas em falha visível.

O modo estrito é útil depois que a política foi criada. Adotá-lo antes de revisar a árvore pode transformar a migração em uma sequência de liberações apressadas.

Aprovar um pacote é aceitar uma capacidade, não marcar uma caixa

O fluxo sugerido pelo npm começa com npm approve-scripts --allow-scripts-pending. A lista aprovada vai para o package.json e deve passar por revisão de código. Antes de aceitar um item, confira qual versão chegou pelo lockfile, qual script será executado e se a finalidade ainda é necessária.

npm ci
npm approve-scripts --allow-scripts-pending

# Depois da revisão, o CI pode recusar itens novos:
npm ci --strict-allow-scripts

Fixar a aprovação somente pelo nome pode ser amplo demais para um pacote que mudou de mantenedor ou comportamento. Quando o projeto exigir uma exceção, documente no mesmo pull request o motivo, a versão analisada, o artefato esperado e como a aplicação denuncia se aquela etapa deixar de funcionar.

O npm também permite negar scripts explicitamente. Essa decisão é útil para dependências opcionais ou rotinas de telemetria que não precisam rodar no seu ambiente. Já --dangerously-allow-all-scripts é uma saída de compatibilidade, não uma política permanente: ele restaura justamente a confiança irrestrita que a versão 12 tentou remover.

Um plano de migração que não paralisa o time

  1. Atualize uma branch para npm 11.16 ou superior e trate os avisos antes da troca de major.
  2. Faça uma instalação limpa e classifique cada script como necessário, substituível ou dispensável.
  3. Aprove ou negue itens individualmente e versione a política no repositório.
  4. Teste imagens de CI, builds nativos e tarefas de empacotamento, não só a suíte unitária.
  5. Atualize para npm 12 e torne scripts novos não revisados uma falha do CI.

Essa sequência complementa uma revisão mais ampla de segurança no npm install. Para organizar a troca de major, o checklist de atualização de dependências ajuda a separar compatibilidade, rollout e rollback.

O padrão mais seguro não elimina a revisão

Scripts desligados reduzem execução inesperada no momento da instalação. Eles não verificam o código que será importado em runtime, não garantem a integridade de um mantenedor e não substituem lockfile, proveniência, atualização controlada ou isolamento de credenciais no CI.

O ganho do npm 12 está em mudar a pergunta. Antes, a árvore executava e o time precisava descobrir se algo era perigoso. Agora, a execução pede uma autorização que pode ser revisada, versionada e revogada. A migração vale quando transforma essa autorização em política explícita — não quando adiciona um atalho global para fazer o build voltar a ficar verde.

Fontes