Principais conclusões
- O Third Coming e o Miasma se valeram de caminhos de publicação confiáveis do CI, em vez de tokens de mantenedores de longa duração que haviam sido roubados.
- Um registro que faz a triagem do conteúdo das versões pode identificar essas publicações mesmo quando a certificação estiver válida.
- Para os pacotes cobertos pelo SecureChain, a recompilação a partir de código-fonte verificado impede que uma republicação feita com credenciais roubadas seja incluída na sua compilação.
- Um período de quarentena só é útil se a versão maliciosa for retirada antes que o prazo expire.
As falhas de segurança no npm ocorrem com tanta frequência que a mesma pergunta sempre surge. Um registro seguro do npm teria realmente evitado esse incidente? A resposta varia de acordo com o mecanismo, que é justamente a parte que a maioria das alegações dos fornecedores omite.
Este artigo analisa os controles efetivos do SecureChain em relação a quatro incidentes ocorridos em 2026: axios, jscrambler, a “Terceira Vinda” de Shai-Hulud e Miasma. Cada um deles é mapeado para o mecanismo responsável por detectá-lo, juntamente com o nível de confiança atribuído a esse mapeamento.
Duas causas fundamentais, e não quatro incidentes distintos
Se classificarmos as quatro campanhas de acordo com o mecanismo, elas se dividem em dois grupos, e não em quatro.
Tanto o caso do axios quanto o do jscrambler se resumiram ao uso de uma credencial de publicação roubada diretamente contra o repositório, com o próprio processo de CI do projeto sendo totalmente contornado. No caso do axios, um invasor acessou a máquina do mantenedor principal por meio de uma campanha direcionada de engenharia social e, em seguida, publicou manualmente duas versões maliciosas em 31 de março. O repositório de código-fonte nunca foi alterado, e não há nenhum commit ou tag relacionado a nenhuma dessas versões. O incidente com o jscrambler, em julho, seguiu o mesmo padrão. O jscrambler confirmou posteriormente que um invasor usou uma credencial de publicação do npm comprometida para enviar cinco versões maliciosas ao longo de aproximadamente três horas, novamente sem que houvesse nada relacionado a elas no repositório.
O Third Coming e o Miasma não se encaixam nesse padrão, e é justamente essa lacuna que justifica a existência deste artigo, em vez de simplesmente fornecer links para os relatórios. Ambos os vulnerabilidades chegaram ao pipeline de compilação, em vez de ao token npm de um mantenedor. No caso do Bitwarden, a forma de acesso foi uma ação do Checkmarx no GitHub comprometida, já utilizada no próprio pipeline do Bitwarden; em seguida, o fluxo de trabalho de lançamento foi editado repetidamente para que um tarball pré-compilado fosse publicado por meio do caminho de publicação npm do Bitwarden, baseado em OIDC. No caso do Miasma, pelo menos 32 pacotes sob o escopo @redhat-cloud-services da Red Hat distribuíram versões maliciosas em 1º de junho, após a conta do GitHub de um funcionário da Red Hat ter sido comprometida. O invasor enviou commits órfãos, que ignoraram completamente a revisão de código, e depois os publicou por meio do caminho OIDC do GitHub Actions do repositório. Nenhum dos invasores precisou das credenciais npm de um mantenedor para fazer com que a publicação parecesse legítima.
Essa distinção é importante para uma avaliação. O Miasma é um exemplo claro disso. O Wiz detectou que o fluxo de trabalho injetado solicitava um token OIDC e publicava pacotes com atestados de proveniência SLSA válidos, pois o fluxo de trabalho que os produziu era, de fato, o pipeline de CI legítimo, apenas acionado por um commit que ninguém autorizou.
O caso da “Third Coming” é mais obscuro. A Endor Labs analisou o histórico público de commits e descobriu que o fluxo de trabalho de lançamento foi editado cinco vezes em rápida sucessão para publicar um arquivo tar em etapas; em uma dessas tentativas, o sinalizador de proveniência foi totalmente removido, e a análise se recusa explicitamente a atribuir a publicação bem-sucedida a qualquer execução específica ou a ser interpretada como uma linha do tempo assinada de resposta a incidentes.
De qualquer forma, o argumento se mantém. Substituir tokens de longa duração pela Publicação Confiável é exatamente o que se recomenda após um incidente de roubo de credenciais, como o do axios, e ambas as campanhas mostram até onde esse conselho é válido, pois um pipeline comprometido pode produzir uma publicação que pareça legítima, independentemente de um atestado válido acabar sendo anexado a ela. Um registro que verificasse apenas a presença de um atestado verde teria deixado o Miasma passar despercebido e não se pode presumir que teria detectado o Third Coming também.
A tradição de nomes também continuou. Em agosto, surgiu uma campanha separada sob a hashtag “Here We Go Again”. Trata-se de um caso à parte, não de uma repetição do “Third Coming”.
Como um registro seguro do npm detecta o que chega ao pipeline
Essa é a parte que importa para o Third Coming e o Miasma, pois nenhum dos dois é afetado pela questão de saber se uma publicação veio de um fluxo de trabalho confiável. Ambos envolviam caminhos de publicação de CI confiáveis.
Quando o bloqueio de scripts de instalação deixa de ser útil
O npm executa os scripts de instalação de um pacote automaticamente, a menos que algo o impeça, e esse foi o mecanismo que a maioria dessas campanhas utilizou inicialmente. A dependência maliciosa do axios foi acionada a partir de um gancho de pós-instalação. As três primeiras versões adulteradas do jscrambler utilizaram o gancho de pré-instalação, assim como a CLI do Bitwarden com backdoor e a onda principal de lançamentos do Miasma.
A partir de npm 12, lançado em julho de 2026, os scripts de instalação de dependências estão desativados por padrão. Os scripts de pré-instalação, instalação e pós-instalação não são mais executados, a menos que um projeto os aprove explicitamente, e o npm também bloqueia a reconstrução implícita do node-gyp que um arquivo no nível raiz binding.gyp arquivo usado para acionar. Essa segunda parte não é mera teoria neste contexto, pois a atualização do Wiz, de 4 de junho, abordou uma nova onda de pacotes Miasma que abusavam de binding.gyp para executar código durante a instalação, o que é exatamente o que acontece quando os scanners estão lendo apenas o bloco de scripts. Em clientes mais antigos, --ignore-scripts abrange o subconjunto de scripts do ciclo de vida e nada além disso.
Além disso, há o limite, e o jscrambler demonstrou isso no mesmo incidente. A partir da versão 8.18.0, o invasor transferiu o dropper idêntico da pré-instalação para uma função autoexecutável no início do dist/index.js, então ele foi executado na importação ou ao usar a CLI, em vez de na hora da instalação, e passou sem problemas npm install --ignore-scripts. Os invasores podem mover a carga maliciosa. Bloquear os scripts de instalação não a remove do pacote.
Por que a triagem de conteúdo ignora a declaração de conformidade
O mecanismo de controle que realmente responde ao Third Coming e ao Miasma ocorre uma etapa antes e analisa a versão lançada, em vez da editora. A triagem de conteúdo pode detectar ganchos de instalação inesperados, código ofuscado sem motivo para estar presente, discrepâncias entre o artefato publicado e o código-fonte do projeto, além de anomalias entre uma versão e outra. O lançamento do Bitwarden mostra o quão evidente esse último sinal pode se tornar, já que a comparação recursiva da Endor Labs detectou package.json anunciava a versão 2026.4.0, enquanto a CLI incluída ainda apresentava a versão 2026.3.0 em seus metadados compactados, o que indica que ela foi reempacotada muito antes de alguém descompilar qualquer coisa.
A explicação da própria SecureChain sobre essa etapa é que cada pacote é recompilado a partir do código-fonte em ambientes fortificados e isolados e submetido a uma triagem em busca de malware conhecido, padrões de código suspeitos e riscos à cadeia de suprimentos, sendo que qualquer item que não passe na inspeção é bloqueado antes de chegar ao seu ambiente. A triagem nessa base não leva em conta se uma publicação chegou por meio de um token pessoal sequestrado ou de um pipeline de CI comprometido com um atestado impecável, pois o atestado não é o que está sendo analisado.
O nível de confiança aqui é moderado a alto, com a mesma ressalva que se aplica ao bloqueio de scripts. Trata-se de detecção, e a detecção envolve uma taxa de falsos negativos. O malware pode atrasar, disfarçar ou fragmentar seu comportamento, e a mudança de estratégia do jscrambler no meio do incidente é um bom lembrete de que os invasores se adaptam ao que quer que os scanners estejam analisando. Ainda assim, é o que mais se aproxima, nesta lista, de responder ao Third Coming e ao Miasma nos próprios termos deles, pois avalia o conteúdo de uma versão em vez de confiar na identidade por trás dela.
O SecureChain como alternativa ao registro do npm contra ataques de sequestro por meio de credenciais roubadas
O axios e o jscrambler são os casos mais simples, e é aí que um substituto do registro do npm mostra seu valor com o mínimo de riscos.
Direcione suas compilações para um catálogo selecionado e recompilado a partir do código-fonte e, para qualquer pacote coberto pelo SecureChain, a versão que você obterá será aquela que a TuxCare compilou a partir do código-fonte verificado em um ambiente fortificado, em vez daquela que foi enviada mais recentemente para o npmjs.com. Um tarball malicioso publicado com um token roubado simplesmente não está nesse caminho. Não importa o quão convincente seja a forma como ele foi empacotado ou a rapidez com que seja sinalizado em outros lugares, pois sua compilação nunca iria consultar a cópia do registro público. O comprometimento do jscrambler é, estruturalmente, o axios com um nome de pacote diferente, portanto, a mesma garantia se aplica a ambos.
Há dois pontos sobre os quais vale a pena ser preciso, pois é ao confundir esses dois que esse argumento acaba sendo exagerado. A cobertura é o primeiro. O SecureChain foi lançado com os pacotes mais utilizados no registro do npm e adicionará um pacote do qual você dependa caso ele ainda não esteja no catálogo; portanto, a garantia acima se aplica aos pacotes cobertos, e não a todos os nomes que uma árvore de dependências venha a incluir. A fidelidade de reprodução é a segunda. Um pacote npm publicado geralmente contém uma saída transpilada ou empacotada, em vez do código-fonte bruto do repositório, e corresponder isso byte a byte significaria reproduzir o próprio ambiente de compilação do editor, o que o ecossistema não garante. Uma recompilação do SecureChain não é um clone bit a bit do tarball do editor, e nunca teve a intenção de ser. Trata-se de uma compilação com origem rastreável, o que é uma propriedade diferente e mais útil quando o tarball do editor é justamente aquilo em que você deixou de confiar.
Essa rastreabilidade é o objetivo dos metadados que acompanham os pacotes. Os pacotes do SecureChain são compilados e assinados para oferecer suporte à proveniência SLSA Nível 3, com compilações executadas a partir de fontes verificadas e respaldadas por testes contínuos; além disso, a TuxCare publica metadados SBOM e VEX sempre que disponíveis. A cobertura do SBOM varia de acordo com o pacote e ainda está em expansão, no formato SPDX ou CycloneDX, dependendo do pacote; portanto, verifique a documentação atual em vez de presumir um conjunto uniforme.
Uma janela de quarentena é determinística em relação a versões de curta duração
Filtragem, bloqueio de script, recompilação a partir do código-fonte. Todas as três funcionam ao reconhecer que algo está errado. Uma janela de quarentena não precisa reconhecer nada.
Se a resolução de um problema em uma versão recém-publicada for adiada por tempo suficiente, uma versão lançada dentro desse intervalo nunca será elegível para chegar à compilação. Nada é analisado, e não há classificador com uma taxa de falsos negativos a ser ajustada. A duração do intervalo e quaisquer exclusões ainda são decisões de configuração, mas são do tipo que você pode definir em um quadro branco. O problema, porém, está na formulação. A idade por si só não torna uma versão segura. Ela apenas dá tempo para que outra pessoa a detecte. Uma versão maliciosa que permanece ativa além do período de atraso se torna elegível como qualquer outra versão, que foi exatamente o que aconteceu com o jscrambler 8.14.0.
| Incidente | Janela de exposição | Sujeito a uma quarentena de 24 horas |
|---|---|---|
| axios | Aproximadamente 3 horas, das 00h21 às 03h15 UTC do dia 31 de março | Sim, ambas as versões foram retiradas bem dentro dele |
| Shai-Hulud “A Terceira Vinda” | 93 minutos, das 21h57 às 23h30 UTC do dia 22 de abril | Sim, está obsoleto bem no meio disso |
| Miasma | Duas ondas de commits em 1º de junho; a maioria das versões foi revogada até as 13h UTC | É provável, mas não está confirmado para todas as versões |
| jscrambler | Cinco versões ao longo de aproximadamente 3 horas no dia 11 de julho | Em parte, porque a versão 8.14.0 nunca foi removida do registro |
Dois desses casos representam vitórias confirmadas da aritmética sobre a análise. O jscrambler é o contraexemplo. O Miasma fica no meio termo, pois o Wiz informou que a maioria das versões maliciosas havia sido revogada até as 13h UTC, com duas ainda ativas naquele momento, o que comprova uma remoção parcial rápida, mas não se todas as versões haviam desaparecido antes que o prazo de 24 horas expirasse.
A contrapartida também é real. Um período de quarentena significa ficar um pouco atrasado nas atualizações legítimas, e as equipes que trabalham com dependências upstream em rápida evolução sentem isso mais intensamente do que as equipes em plataformas internas mais lentas. É também um dos controles mais simples de se implementar aqui e o mais propenso a ser descartado em uma avaliação por parecer simples demais para realmente fazer diferença.
Segurança do registro privado do npm: além do cache pull-through
A mudança só importa se funcionar no dia a dia; portanto, eis a parte operacional.
A integração consiste em duas linhas em .npmrc, uma linha de registro e a linha de autenticação para esse host, usando o token CLN que a TuxCare lhe fornece, substituindo YOUR_CLN_TOKEN pelo valor real:
registry=https://artifacts.tuxcare.com/npm/
//artifacts.tuxcare.com/npm/:_authToken=YOUR_CLN_TOKEN
package.json não muda. Os nomes e as versões permanecem os mesmos, e o mesmo endpoint atende às compilações do SecureChain, quando existentes, além do pacote público do upstream para todo o restante; portanto, não há necessidade de configurar um segundo registro.
Há um detalhe que vale a pena testar antes de uma implementação em larga escala. package-lock.json registra, entre outras coisas, uma URL resolvida indicando a origem de cada arquivo tar e um hash de integridade dos bytes desse arquivo tar. É esperado que a URL resolvida mude quando você troca de servidor. O hash de integridade é o que chama a atenção. Um hash é validado em relação a um tarball com bytes idênticos proveniente de qualquer host; portanto, uma simples mudança de host não o afetaria, mas uma reconstrução do SecureChain, por definição, não é byte a byte idêntica ao artefato público. Essa incompatibilidade é o que aparece como EINTEGRITY quando um arquivo de bloqueio antigo do Registro Público encontra um novo Registro por baixo dele.
Portanto, planeje a regeneração do arquivo de bloqueio, em vez de uma comparação superficial. Exclua node_modules e package-lock.json, execute uma instalação nova com base no novo registro e, em seguida, confirme o arquivo de bloqueio gerado, que registra as URLs do SecureChain e as somas de verificação. Faça isso primeiro em um branch temporário ou em um clone, para que o diff seja algo que você mesmo analise, em vez de algo que a integração contínua (CI) descubra por você. Em seguida, decida antecipadamente se a alteração será aplicada como um commit independente em todos os repositórios de uma só vez ou se será implementada gradualmente. Misturar uma mudança de registro em um branch de recurso é a maneira pela qual a configuração acaba sendo revertida discretamente por alguém que nem sabia que ela existia.
Mais duas etapas transformam a sugestão em uma medida obrigatória. Mude o CI para npm ci onde quer que ainda esteja em execução npm install, já que npm ci realiza as instalações a partir do arquivo de bloqueio confirmado e falha quando o arquivo de bloqueio e package.json discorde, em vez de atualizá-la discretamente. Em seguida, bloqueie o acesso de saída para registry.npmjs.org a partir dos agentes de compilação, pois, até que isso seja resolvido, a configuração do registro em .npmrc é uma sugestão que qualquer pessoa pode rejeitar para desbloquear uma implantação.
Teste esse bloqueio de saída no ambiente de teste antes de aplicá-lo em todos os lugares. Qualquer falha que ocorrer nesse ambiente indicará quais pipelines e ferramentas têm contornado a configuração do registro, e é muito melhor ter essa lista documentada do que como um incidente.
Argumentos a favor de um registro npm diferente
A triagem de conteúdo e a reconstrução e resolução abrangem diferentes modos de falha, não o mesmo duas vezes. A triagem se aplica ao “Third Coming” e ao “Miasma”, pois não depende da origem de uma publicação. A reconstrução e a resolução a partir de um catálogo selecionado se aplicam ao “axios” e ao “jscrambler”, pois, para um pacote coberto, o artefato malicioso nunca entra no caminho a partir do qual sua compilação é resolvida, com o respaldo de artefatos assinados e proveniência SLSA Nível 3.
Se sua equipe ainda estiver fazendo a resolução diretamente do registro público, solicite um orçamento do SecureChain para npm e veja quanto custaria para sanar essa lacuna.
Perguntas frequentes
O que é um registro seguro do npm?
Uma camada de registro que disponibiliza pacotes recompilados e avaliados para as dependências que abrange, em vez de simplesmente repassar o artefato do editor. Na prática, trata-se de uma combinação: compilações do SecureChain, quando disponíveis, e pacotes públicos do upstream para o restante, todos disponibilizados por meio do mesmo endpoint. Isso difere de um cache de repasse, que melhora a disponibilidade e a velocidade sem inspecionar nada que passe por ele.
Um registro seguro do npm teria impedido a campanha “A Terceira Vinda de Shai-Hulud”?
Isso é possível, desde que o registro analise o conteúdo independentemente da identidade do editor. Nunca se constatou se a própria versão maliciosa possuía um atestado válido; portanto, não se pode confiar apenas em verificações baseadas na identidade neste caso. Uma etapa de triagem que analise o conteúdo de uma versão — como um novo gancho de compilação, código ofuscado ou arquivos sem commit correspondente — pode detectar isso independentemente do que o atestado indique. O Miasma é o exemplo mais claro desse mesmo modo de falha, já que essas versões possuíam uma proveniência SLSA válida e assinada.
Um período de quarentena teria impedido o Axios?
Sim. As versões maliciosas permaneceram ativas por cerca de três horas e foram retiradas em seguida; portanto, um atraso de um dia na adoção — o menor que o npm pode expressar — teria mantido essas versões inelegíveis durante todo o período em que estiveram ativas, sem que fosse necessário identificar nada como malicioso. Essa barreira é a configuração `min-release-age`, que recebe um valor em dias e requer o npm 11.10.0 ou mais recente, já que clientes mais antigos a ignoram silenciosamente. Ela controla a resolução de dependências em vez de atuar como uma verificação retroativa; portanto, uma versão maliciosa já fixada em um arquivo de bloqueio confirmado é um problema à parte.
O que uma alternativa ao registro do npm realmente muda no dia a dia?
Principalmente de onde os comandos de instalação são resolvidos. package.json e a maioria dos fluxos de trabalho permanece a mesma. package-lock.json precisa ser regenerado uma vez, pois tanto a URL resolvida quanto o hash de integridade nela contido referem-se a artefatos do registro antigo.
A segurança de um registro privado do npm é garantida simplesmente com a criação desse registro privado?
Por si só, não. Um proxy de cache oferece um ponto de controle sobre a origem dos pacotes, mas esse ponto de controle não garante que o que passa por ele seja confiável. O fato de as instalações se tornarem realmente mais seguras depende do que é executado nesse ponto de controle e se os caminhos alternativos também estão bloqueados. A CI que ainda faz a resolução diretamente do registro público continua sendo a lacuna mais comum.
