npmjavascriptsecuritynews

npm Security 2025: Por Que Proveniência e Sigstore Mudam Tudo

Do worm 'Shai-Hulud' ao typosquatting, 2025 foi brutal para o npm. Descubra como fortalecer sua cadeia de suprimentos com proveniência, Sigstore e Publicação Confiável.

DataFormatHub Team
December 22, 202512 min read
Share:
npm Security 2025: Por Que Proveniência e Sigstore Mudam Tudo

O ecossistema de pacotes JavaScript, particularmente o npm, sempre foi vibrante, se ocasionalmente caótico. Mas, ao final de 2025, o ar está denso com um tipo diferente de energia: uma urgência palpável em direção a uma cadeia de suprimentos de software mais segura. Ataques recentes de alto perfil mudaram a conversa de "se" para "como" fortaleceremos coletivamente nossas dependências. Tenho estado nas trincheiras, testando as últimas ferramentas e observando a evolução da situação, e, honestamente, alguns dos avanços são genuinamente impressionantes, mesmo que o caminho para a adoção completa ainda esteja repleto de alguns espinhos complicados.

Isso não se trata apenas de correção de bugs; é uma reavaliação fundamental da confiança, da proveniência e da própria mecânica de como consumimos e publicamos código. A boa notícia? Estamos vendo esforços reais e tangíveis da equipe principal do npm, do GitHub e da comunidade em geral para abordar essas vulnerabilidades sistêmicas.

A Ascensão do npm provenance e Sigstore: Confiança na Fonte

Isso é genuinamente impressionante porque aborda uma das ameaças mais insidiosas: um ambiente de construção ou publicação comprometido. Por anos, confiamos no campo integrity do package.json para checksums, mas isso apenas verifica o pacote baixado em relação ao que o registro acha que deveria ser. Não nos diz se o pacote foi construído e publicado pelo mantenedor legítimo em um ambiente confiável. Entre o npm provenance, disponível geralmente desde outubro de 2023, com um impulso significativo em 2024 e 2025.

npm provenance é a implementação do npm do framework Supply-chain Levels for Software Artifacts (SLSA), aproveitando o poder do Sigstore. A ideia central é criar atestações verificáveis sobre como e onde um pacote foi construído e publicado. Ao publicar um pacote com --provenance, o CLI do npm funciona com seu provedor de CI/CD (atualmente GitHub Actions e GitLab CI/CD são suportados) para gerar uma atestação de proveniência. Essa atestação inclui detalhes como o URI do repositório de origem, hash do commit e instruções de construção.

Aqui está a elegância arquitetural: Em vez de gerenciar chaves de assinatura de longa duração, o Sigstore usa certificados efêmeros de curta duração emitidos por uma Autoridade de Certificação (Fulcio) que se federam com seu provedor OIDC. Este certificado é então usado para assinar a declaração de proveniência, e tanto o certificado quanto a assinatura são registrados em um log de transparência público e à prova de adulteração (Rekor). Isso significa que você assina a construção, descarta a chave privada e todo o processo é auditável publicamente.

Para publicar com proveniência, é tão simples quanto adicionar um sinalizador:

npm publish --provenance --access public

E para verificação? O comando npm audit signatures, introduzido em julho de 2022, é agora nosso melhor amigo para isso. Ele verifica assinaturas ECDSA e gerará um erro se os pacotes tiverem assinaturas ausentes ou inválidas, indicando possível adulteração.

npm audit signatures

Este é um passo monumental para frente. Embora não garanta a ausência de código malicioso, ele fornece um link criptográfico de volta à fonte e ao ambiente de construção, capacitando os desenvolvedores a tomar decisões de confiança informadas. A limitação, por enquanto, é sua dependência de runners hospedados na nuvem e provedores de CI/CD específicos. Para aqueles de nós com runners auto-hospedados ou sistemas de CI alternativos, a adoção ainda é um pouco complicada, exigindo soluções alternativas manuais ou aguardando um suporte mais amplo. Mas a direção está clara e é robusta.

Fortalecendo o Publicador: 2FA, Tokens Granulares e Publicação Confiável

A onda de ataques à cadeia de suprimentos em 2025, incluindo o worm "Shai-Hulud" em setembro e campanhas subsequentes de typosquatting em outubro, serviu como um duro despertar. Os invasores comprometeram contas de mantenedores por meio de phishing sofisticado, levando a injeções de pacotes maliciosos. O GitHub, que é proprietário do npm, respondeu com mudanças agressivas e necessárias na autenticação e publicação, lançadas amplamente entre outubro e meados de novembro de 2025.

As principais mudanças são:

  1. 2FA Obrigatório para Publicação Local: Esta é uma grande vitória. Não há mais publicação de uma máquina local apenas com uma senha. Se você estiver publicando do seu ambiente de desenvolvimento, o 2FA será obrigatório. Isso aborda diretamente os vetores de phishing que atormentaram os mantenedores.
  2. Descontinuação de Tokens Clássicos Legados: Tokens npm clássicos, frequentemente de longa duração e com escopo amplo, estão sendo descontinuados. Isso é crítico porque tokens de longa duração comprometidos foram um vetor de ataque primário.
  3. Vida Útil Limitada para Tokens Granulares: Novos tokens granulares, que permitem permissões mais específicas, terão uma vida útil máxima de sete dias (com um máximo de 90 dias para alguns casos). Isso reduz drasticamente a janela de oportunidade para invasores se um token for roubado.
  4. Expansão da Publicação Confiável: O suporte do npm para Publicação Confiável, introduzido em julho de 2025, remove a necessidade de gerenciar tokens de API em sistemas CI/CD. Em vez disso, os provedores de CI/CD (como o GitHub Actions) podem atestar diretamente a identidade do publicador, e o npm verifica essa atestação. Este é o padrão ouro, pois elimina o token como um segredo em seu pipeline de construção.

A transição, embora necessária, causou alguma interrupção no fluxo de trabalho para os desenvolvedores acostumados às práticas mais antigas. A descontinuação do 2FA TOTP em favor do 2FA baseado em FIDO (como WebAuthn/passkeys) também é uma mudança significativa, pois a autenticação resistente a phishing é demonstradamente superior ao TOTP contra ataques sofisticados. Embora alguns desenvolvedores possam achar a mudança para passkeys desafiadora devido à compatibilidade do dispositivo, os benefícios de segurança são inegáveis.

Para aqueles que publicam do CI, a recomendação é usar npm publish --provenance com a configuração de Publicadores Confiáveis, ignorando completamente a necessidade de tokens explícitos em seu ambiente CI. Para publicação local, certifique-se de que seu 2FA esteja atualizado e resistente a phishing.

Além de npm audit: A Paisagem em Evolução da Verificação de Dependências

npm audit é um pilar desde 2018, fazendo um bom trabalho ao sinalizar vulnerabilidades conhecidas em sua árvore de dependências, verificando o Banco de Dados de Consultoria Pública do npm. E, embora seja uma maneira rápida e integrada de identificar problemas, eventos recentes destacaram suas limitações. Um npm audit funciona apenas contra vulnerabilidades conhecidas. Ele não detecta malware novo, ataques sutis à cadeia de suprimentos que modificam pacotes legítimos ou vulnerabilidades em seu próprio código.

O worm "Shai-Hulud", por exemplo, comprometeu pacotes e os republicou com malware. Embora npm audit possa eventualmente detectar as novas versões maliciosas se as consultorias forem publicadas, a disseminação inicial pode ser rápida. Isso sublinha a necessidade de uma abordagem em camadas.

É aqui que ferramentas especializadas realmente brilham. Soluções como Snyk e SonarQube vão muito mais fundo. Snyk, por exemplo, oferece detecção de vulnerabilidades em tempo real em dependências, monitoramento contínuo e até mesmo solicitações de pull automatizadas para aplicar correções. SonarQube, embora mais amplo em escopo para qualidade de código, também fornece análise de segurança abrangente para JavaScript e Node.js, capaz de interromper as construções se os limites de segurança não forem atendidos.

Integrar essas ferramentas em pipelines de CI/CD não é mais um "nice-to-have", mas um "must-have". Uma configuração típica pode envolver:

  1. Hooks de pré-commit: Executar linters básicos e análise estática para detectar problemas óbvios no início.
  2. Etapa de construção do CI: Executar npm audit para uma verificação rápida, mas, mais importante, integrar uma ferramenta SCA (Software Composition Analysis) robusta como Snyk ou uma ferramenta SAST (Static Application Security Testing) como SonarQube.
  3. Monitoramento pós-implantação: Verificar continuamente aplicativos implantados e suas dependências em busca de vulnerabilidades recém-descobertas.

A realidade aqui é que, embora npm audit seja acessível, é uma linha de base. Confiar apenas nele em 2025 é como trazer uma faca de manteiga para uma briga de armas. As ferramentas comerciais e de código aberto avançadas, embora exijam mais configuração e potencialmente custo, oferecem a profundidade necessária para realmente proteger aplicativos modernos.

Segurança em Tempo de Execução Reimaginada: Permissões do Deno e a Visão do JSR

Embora o npm seja o gerenciador de pacotes dominante para Node.js, o ecossistema JavaScript mais amplo está vendo uma evolução fascinante em runtimes, com Deno e Bun desafiando a hegemonia do Node.js. O que é emocionante é como suas filosofias estão influenciando a segurança. Entender as diferenças entre Node.js, Deno, Bun em 2025: Escolhendo Seu Runtime JavaScript é agora um pré-requisito para uma arquitetura segura.

Deno: Segurança Primeiro por Padrão

Deno, criado pelo fundador do Node.js Ryan Dahl, tem segurança incorporada em seu núcleo. Ao contrário do Node.js, que concede acesso irrestrito ao sistema por padrão, o Deno opera com um modelo de permissões em sandbox. Isso significa que um programa Deno não pode acessar o sistema de arquivos, a rede ou as variáveis de ambiente sem permissão explícita.

Por exemplo, para permitir acesso à rede e leitura do sistema de arquivos, você executaria seu script Deno com sinalizadores:

deno run --allow-net --allow-read app.ts

Este modelo de permissão explícito é uma mudança de jogo para prevenir ataques à cadeia de suprimentos, onde pacotes maliciosos frequentemente tentam exfiltrar dados ou comprometer o sistema host. Se uma dependência comprometida tentar fetch dados de um domínio não autorizado ou read arquivos confidenciais, o Deno simplesmente negará, a menos que você tenha concedido explicitamente essa permissão.

JSR: Um Novo Registro para JavaScript Moderno

Introduzido em beta público em março de 2024, JSR (JavaScript Registry) é a resposta do Deno a um registro de pacotes moderno. JSR não se destina a bifurcar o npm, mas a construir sobre seu sucesso, adotando ESM, suporte nativo a TypeScript e um foco em segurança e experiência do desenvolvedor.

Um dos recursos de segurança de destaque do JSR é a "publicação segura e sem token". Semelhante à Publicação Confiável do npm, o JSR visa proteger contra ataques à cadeia de suprimentos, eliminando a necessidade de tokens de longa duração durante o processo de publicação. O JSR também se concentra na proveniência completa dos pacotes publicados, garantindo informações de construção verificáveis.

Bun: Velocidade com Segurança em Evolução

Bun, o novato construído em Zig, prioriza a velocidade bruta em todos os aspectos: tempo de execução, instalação de pacotes, agrupamento e teste. Embora o Bun seja incrivelmente rápido e ofereça compatibilidade com npm, seu modelo de segurança é atualmente mais semelhante ao Node.js, com acesso irrestrito por padrão.

No entanto, o ciclo de desenvolvimento rápido do Bun sugere que recursos de segurança mais explícitos podem estar no roteiro. Por enquanto, se você estiver aproveitando o incrível desempenho do Bun, é crucial fortalecer sua segurança com verificação de dependências robusta e salvaguardas de CI/CD, pois seu sandboxing nativo não é tão maduro quanto o do Deno.

O Papel Crucial de package-lock.json e SRI: Integridade Que Você Não Pode Ignorar

O arquivo package-lock.json é muito mais do que apenas uma lista de versões fixadas; é um manifesto criptográfico de sua árvore de dependências. Seu campo integrity, especificamente, contém um hash de Integridade de Sub-recursos (SRI), normalmente SHA512, para cada pacote. Este hash é uma impressão digital exclusiva do conteúdo do pacote como foi originalmente publicado no registro.

Quando você executa npm install (ou npm ci em CI/CD, o que é altamente recomendado para reprodutibilidade), o npm baixa o pacote, recalcula seu hash e o compara com o valor integrity em seu package-lock.json. Se eles não corresponderem, a instalação falhará, sinalizando possível adulteração. Esta é nossa primeira e, muitas vezes, mais crítica linha de defesa contra invasores que modificam pacotes no registro ou durante o trânsito.

No entanto, este mecanismo não é à prova de todos os ataques à cadeia de suprimentos. O vetor de ataque "envenenamento do lockfile" demonstra isso: se um invasor obtiver controle sobre a conta de um mantenedor, ele poderá publicar uma versão maliciosa de um pacote e, em seguida, atualizar o package-lock.json no repositório legítimo com o hash de integridade novo e malicioso. Se este package-lock.json comprometido for confirmado e npm install ou npm ci for executado, o pacote malicioso será instalado porque o hash de integridade corresponde à versão do invasor.

É por isso que npm provenance é tão crucial como uma camada de defesa adicional, provando quem publicou o pacote e como ele foi construído. Ele adiciona uma "fonte da verdade" além do hash.

Os desenvolvedores devem sempre:

  • Confirmar package-lock.json: Isso garante instalações determinísticas e fornece os hashes de integridade para verificação.
  • Revisar as diferenças de package-lock.json em PRs: Procure por alterações inesperadas, especialmente em versões de pacotes ou hashes de integridade, o que pode indicar um invasor tentando injetar uma dependência comprometida.
  • Garantir que SHA-512 seja usado: Arquivos package-lock.json mais antigos podem usar SHA-1, que é criptograficamente fraco e vulnerável a ataques de colisão. As versões modernas do npm usam SHA-512 por padrão, mas se você estiver em um projeto mais antigo, uma nova instalação do npm install após excluir node_modules e package-lock.json (e, em seguida, confirmar o novo) pode atualizar esses hashes.
# Para forçar a atualização para SHA512 (use com cautela, confirme as alterações após!)
rm -rf node_modules package-lock.json
npm install

Defendendo Contra Ataques de Script de Ciclo de Vida: A Ameaça Silenciosa

Um dos recursos mais poderosos – e perigosos – dos pacotes npm são os scripts de ciclo de vida. São comandos shell arbitrários definidos em package.json (por exemplo, preinstall, install, postinstall, prepack, prepare) que são executados em vários estágios do processo de instalação ou publicação do pacote. Embora incrivelmente úteis para compilação, configuração ou construção de módulos nativos, eles também são um vetor primário para ataques à cadeia de suprimentos.

Um script postinstall malicioso, por exemplo, pode executar código arbitrário na máquina de um usuário imediatamente após um pacote ser instalado. Isso pode variar desde roubar variáveis de ambiente e credenciais até instalar malware adicional. Os ataques de typosquatting de outubro de 2025, que usaram infostealers de várias etapas e lançaram terminais ocultos para extrair senhas do sistema e cookies do navegador, aproveitaram muito os scripts postinstall.

Defender-se contra isso requer uma abordagem multifacetada:

  1. Sinalizador --ignore-scripts: Para implantações de produção ou ao auditar novas dependências, executar npm install --ignore-scripts pode impedir que esses scripts sejam executados. Esta é uma salvaguarda crucial, especialmente em ambientes de CI/CD, onde você deseja minimizar a superfície de execução.
    npm install --ignore-scripts
    # Ou via variável de ambiente para efeito global
    NPM_CONFIG_IGNORE_SCRIPTS=true npm install
    
  2. Revisão Cuidadosa de package.json: Ao adicionar novas dependências, sempre inspecione seu package.json em busca de scripts de ciclo de vida suspeitos. Se um pacote utilitário simples tiver um script postinstall complexo, é um sinal de alerta.
  3. Ambientes em Sandbox: Executar npm install dentro de ambientes ou contêineres em sandbox pode limitar o raio de impacto de um script malicioso.
  4. Análise Estática: Ferramentas de segurança avançadas podem frequentemente detectar padrões suspeitos em scripts de ciclo de vida.

O Caminho Adiante: Um Ecossistema Mais Resiliente

Olhando para trás para 2024 e 2025, está claro que o ecossistema de pacotes JavaScript passou por momentos difíceis, mas está emergindo mais forte. Os ataques recentes, embora dolorosos, aceleraram a adoção de recursos de segurança críticos. Estamos nos movendo em direção a:

  • Identidade e Proveniência Mais Fortes: npm provenance e Sigstore são revolucionários, oferecendo links verificáveis do pacote publicado de volta à fonte e à construção. Isso muda a confiança de "Espero que isso seja bom" para "Posso verificar que isso foi construído conforme o esperado".
  • Fluxos de Trabalho de Publicação Fortalecidos: 2FA obrigatório, tokens de curta duração e Publicação Confiável estão tornando significativamente mais difícil para os invasores comprometerem contas de mantenedores e injetarem código malicioso. Esta é uma defesa prática e robusta contra phishing.
  • Verificação Sofisticada: Embora npm audit permaneça útil, a crescente dependência de ferramentas SCA e SAST avançadas, integradas profundamente ao SDLC, é crucial para detectar ameaças novas e conhecidas.
  • Segurança em Tempo de Execução: O modelo de permissões de segurança inerente do Deno e o registro JSR focado na segurança estão ultrapassando os limites do que é possível em um ambiente JavaScript seguro. Estes não são apenas "alternativas", mas "inovações" que influenciarão todo o ecossistema.

No entanto, ainda não estamos fora de perigo. A escala do ecossistema npm (4,5 trilhões de solicitações apenas em 2024) significa que ele continua sendo um alvo principal. A adoção desses novos recursos de segurança não é universal e os projetos legados continuarão a apresentar desafios. A experiência do desenvolvedor ainda pode ser complicada ao integrar novas medidas de segurança e a documentação para alguns recursos experimentais (como o Modelo de Permissões experimental do Node.js, que ainda está evoluindo) pode ser escassa.

Minha opinião? Abrace essas mudanças com entusiasmo. Integre npm publish --provenance em seu CI/CD. Exija 2FA resistente a phishing para sua equipe. Não apenas execute npm audit; invista em varredura mais profunda. Examine package-lock.json e pense duas vezes antes de habilitar scripts de ciclo de vida de fontes desconhecidas. O ecossistema JavaScript é mais resiliente do que nunca, mas sua força depende, em última análise, de nossa vigilância coletiva e da vontade de adotar essas medidas de segurança práticas e eficientes. Estamos construindo o futuro e torná-lo seguro é nossa responsabilidade compartilhada.


Fontes


🛠️ Ferramentas Relacionadas

Explore estas ferramentas DataFormatHub relacionadas a este tópico:


📚 Você Também Pode Gostar