Aikido

O Shai-Hulud foi o melhor que aconteceu à segurança da cadeia de abastecimento

Talvez tenhamos de agradecer ao Shai-Hulud por ter convencido a comunidade a utilizar a publicação «Trusted»

Escrito por
Charlie Eriksen

O npm lançou o «Package Provenance» no final de 2022. Durante dois anos, a adoção situou-se, em média, entre 20 e 50 pacotes por semana. Seguiu-se o «Trusted Publishing» em 2024. Foram publicados artigos no blogue. Foram emitidos alertas da CISA. A situação praticamente não evoluiu. Por fim, o «Trusted Publishing» com OIDC foi disponibilizado ao público em julho de 2025

Foi então que o Shai-Hulud atacou. A adoção semanal disparou para 430 pacotes. Em 18 meses, a adoção cumulativa cresceu 3,4 vezes. Ainda estamos apenas a 25 % do volume total de downloads abrangido; apenas 11 001 dos 51 370 pacotes mais populares adotaram a solução. Mas os ataques tiveram um impacto maior do que qualquer outra medida tomada pelo setor da segurança.

Aqui estão os dados.

O que é a «Trusted Publishing»

O Trusted Publishing substitui os tokens da API do npm de longa duração por credenciais de curta duração, válidas apenas por execução, emitidas através do OpenID Connect. Em vez de armazenar o NPM_TOKEN no seu repositório do GitHub secrets indefinidamente, o seu pipeline de CI recebe um token que expira em minutos. Não há nada para roubar. Não há nada para extrair.

A onda de ataques que mudou tudo

26 de agosto de 2025: S1ngularity. Os atacantes exploraram uma configuração incorreta do GitHub Actions no monorepo do Nx para executar código a partir de um fork malicioso no contexto de confiança do repositório upstream, roubando o token de publicação do npm. Versões maliciosas de vários pacotes Nx estiveram ativas durante quatro horas, a analisar os computadores dos programadores em busca de credenciais, chaves SSH e carteiras de criptomoedas — e, em particular, a procurar ativamente por ferramentas CLI de IA instaladas para as executar com a opção --dangerously-skip-permissions e extrair o conteúdo do sistema de ficheiros. Nessa semana: a adoção registou um aumento notável pela primeira vez.

8 de setembro de 2025: Debug/Chalk. Um mantenedor foi vítima de um ataque de phishing através de um e-mail falso do suporte do npm (enviado a partir de npmjs.help) que recolheu as suas credenciais e o código TOTP ativo. 18 pacotes, com mais de 2 mil milhões de downloads semanais no total, foram infetados com um código malicioso destinado ao roubo de criptomoedas, que interceptava silenciosamente as interações da carteira no navegador e redirecionava fundos. As versões maliciosas permaneceram ativas durante duas horas. Nessa semana: 103 novos pacotes adotaram o Trusted Publishing.

15 de setembro de 2025: Onda 1 do Shai-Hulud. Um worm auto-replicante atingiu o ecossistema do npm. Quando um pacote comprometido encontrava tokens adicionais do npm no seu ambiente, publicava automaticamente versões maliciosas de tudo o que conseguisse alcançar. Resultado: mais de 700 pacotes comprometidos, 27 000 repositórios GitHub maliciosos, 14 000 endereços secrets expostos em 487 organizações. A CISA emitiu um alerta a 23 de setembro. Nessa semana: 109 novos pacotes.

23 de novembro de 2025: Shai-Hulud 2.0. Um pedido de «Pwn» contra o repositório asyncapi/cli exfiltrou o token de CI em menos de três minutos, tendo-o depois utilizado para implementar o worm através de uma extensão maliciosa do OpenVSX. A campanha alastrou-se a mais de 25 000 repositórios maliciosos. A Microsoft publicou orientações a 9 de dezembro. Nessa semana: 372 novos pacotes. A média semanal dos dois anos anteriores situava-se em cerca de 40.

24 de novembro de 2025: SHA1-Hulud. Uma onda paralela atingiu o Zapier, a ENS Domains e outras empresas. Foram encontradas credenciais de longa duração em repositórios comprometidos. A equipa de segurança do npm recomendou explicitamente a «Trusted Publishing» como solução. Nessa semana: 120 novos pacotes.

20–21 de março de 2026: CanisterWorm. A TeamPCP lançou um worm npm através de tokens roubados. Mais de 28 pacotes foram infetados em menos de 60 segundos; a carga útil recolheu credenciais e propagou-se automaticamente. Nessa semana: 112 novos pacotes.

31 de março de 2026: Axios. Sapphire Sleet (Coreia do Norte) comprometeu uma conta de mantenedor e publicou duas versões com backdoor, com um intervalo de 39 minutos entre elas, cada uma das quais injetava uma dependência falsa que descarregava silenciosamente um trojan de acesso remoto multiplataforma. Os pacotes maliciosos permaneceram ativos durante três horas. O Axios tem mais de 100 milhões de descargas semanais. Nessa semana: 138 novos pacotes.

8 a 22 de abril de 2026: CanisterSprawl. Um segundo worm npm da TeamPCP que utilizava um novo canister ICP. Quando foram descobertos tokens PyPI em ambientes infetados, o worm propagou-se por diferentes ecossistemas através da injeção de ficheiros .pth. Nessa semana: 163 novos pacotes.

29–30 de abril de 2026: Mini Shai-Hulud I. A TeamPCP passou de roubo de tokens para roubo de credenciais do CI. Um ataque que abrangeu vários ecossistemas atingiu o npm, o PyPI e o Packagist em 24 horas através de tokens do CircleCI comprometidos. Nessa semana: 121 novos pacotes.

7 a 11 de maio de 2026: Mini Shai-Hulud II / TanStack. Eis a escalada que muda tudo: eles não roubaram um token. A TeamPCP utilizou um Pwn Request para contaminar a cache do GitHub Actions e, em seguida, aguardou que o fluxo de trabalho de lançamento legítimo fosse executado. Quando isso aconteceu — com o id-token: permissões de escrita —, o código controlado pelo atacante, proveniente do cache corrompido, extraiu o token OIDC da memória do executor e trocou-o através do próprio ponto de extremidade de tokens do npm. Os pacotes publicados apresentavam atestados de proveniência SLSA Build Level 3 válidos. A publicação confiável não foi contornada. Foi utilizada como vetor de ataque. Mais de 170 pacotes no npm e no PyPI em 5 horas.

18–19 de maio de 2026: Mini Shai-Hulud III / Nx & AntV. A extensão VS Code da Nx Console foi comprometida utilizando credenciais roubadas durante o ataque TanStack — cinco dias de permanência no sistema antes de serem utilizadas. 639 versões @antv do npm foram adulteradas através de uma conta de mantenedor roubada, cada uma a instalar um backdoor «kitty-monitor» persistente. Nessa semana: 144 novos pacotes. Na semana seguinte: 430. Um recorde histórico.

1 a 7 de junho de 2026: Miasma / Hades. A estratégia de ataque mudou novamente. A Onda 1 publicou 90 versões maliciosas do npm direcionadas a pacotes do Red Hat Cloud Services — não através do roubo de tokens OIDC, mas sim abusando diretamente do ponto final de publicação do OIDC. A Onda 2 introduziu uma técnica «binding.gyp» para contornar a deteção de scripts de instalação. Na onda 4 (Hades), a campanha tinha-se expandido para o PyPI através da execução de ficheiros .pth de arranque, contaminando 37 wheels em 19 pacotes. A Red Hat emitiu o RHSB-2026-006. Nessa semana: 209 novos pacotes.

O padrão e a forma como se agravou

Os primeiros ataques seguiram um padrão já conhecido: fazer phishing a um mantenedor, roubar um token de longa duração, publicar malware e alastrá-lo a tudo o que o token conseguisse alcançar. O caso «Debug/Chalk» foi um ataque de phishing. O caso «Axios» resultou do comprometimento da conta de um mantenedor.

Mas os ataques mais sofisticados visaram o próprio pipeline de CI. Tanto o S1ngularity como o Shai-Hulud 2.0 utilizaram «Pwn Requests», pedidos de pull maliciosos que exploravam fluxos de trabalho vulneráveis do GitHub Actions denominados «pull_request_target» para executar código do atacante dentro do contexto de confiança do repositório upstream. Não precisaram de roubar um token armazenado. Bastava que o executor de CI tivesse um.

O Mini Shai-Hulud II foi o desfecho lógico de uma evolução. Assim que se controla o «runner», é possível extrair quaisquer credenciais ambientais que estejam presentes, incluindo tokens OIDC de curta duração. Os pacotes que publicou pareciam legítimos em todas as verificações automatizadas: proveniência válida, identidade real do mantenedor, assinatura correta. O ataque tinha evoluído da exploração de « secrets » armazenadas para a exploração do próprio processo de compilação.

O Miasma intensificou-se ainda mais. Nem sequer precisava de extrair um token: explorava diretamente o ponto final de publicação do OIDC. Cada onda introduzia uma nova técnica para contornar a deteção. As análises pós-incidente continuavam a apontar as mesmas falhas. Os ataques continuavam a encontrar novas formas de contornar as correções recomendadas.

Attack Data Novos pacotes nessa semana
Lançamento de uma funcionalidade Dezembro de 2022 4
Média de 2 anos 2023-2024 ~35
S1ngularidade 26 de ago. de 2025 52
Depuração/Giz 8 de setembro de 2025 103
Shai-Hulud v1 15 de setembro de 2025 109
Shai-Hulud 2.0 23 de nov. de 2025 372
SHA1-Hulud 24 de novembro de 2025 120
CanisterWorm 20 de mar de 2026 112
Axios 31 de mar. de 2026 138
CanisterSprawl 8 de abril de 2026 163
Mini Shai-Hulud I 29 de abril de 2026 121
Mini Shai-Hulud II 7 de maio de 2026 126
Mini Shai-Hulud III 18 de maio de 2026 144
Mini Shai-Hulud (pico) 25 de maio de 2026 430
Miasma 1º de junho de 2026 209

A superfície de ataque é agora significativamente menor do que há 18 meses. Não porque o setor da segurança tenha convencido as pessoas. Mas porque os pacotes foram infetados com backdoors e, em seguida, os responsáveis pela manutenção alteraram a sua configuração.

Isso não é um sucesso para a educação em segurança. É um dado que mostra como as decisões em matéria de segurança são, na prática, tomadas.

Quem era esta pessoa?

Durante a campanha Shai-Hulud 2.0, o atacante renomeou a sua conta no GitHub para UnknownWonderer1 — quase certamente uma referência aos «Zensunni Wanderers» de «Dune»: os nómadas perseguidos que se tornaram os Fremen, a única cultura que aprendeu a viver em harmonia com Shai-Hulud. O nome não é obra de alguém que se deparou por acaso com este ecossistema. É o nome de alguém que já tinha refletido sobre o assunto.

A conceção do malware reforça essa interpretação. O S1ngularity não se limitou a extrair credenciais discretamente — injetou um comando de desligamento no perfil do shell, algo que iria, visivelmente, desligar o computador na próxima vez que se abrisse um terminal. Esse não é o comportamento de alguém que tenta manter-se oculto. Todas as campanhas ficaram muito aquém do que poderiam ter feito. Um worm que se autopropaga para mais de 700 pacotes, mas que restringe a sua carga útil, está a fazer uma escolha.

Eles também compreendiam a estrutura de incentivos melhor do que o próprio ecossistema. Os responsáveis pela manutenção raramente são remunerados para proteger os pacotes. O impacto de uma violação recai sobre os utilizadores a jusante, não sobre a pessoa que deixou o token no CI. As plataformas com poder para impor a publicação segura são as que menos sofrem quando algo corre mal. Trata-se de uma falha clássica de ação coletiva — e 40 000 pacotes desprotegidos após três anos de alertas são exatamente o que essa estrutura produz. Este atacante percebeu por que razão nada estava a avançar. E decidiu aplicar um tipo diferente de pressão.

Tiros de aviso

Na altura, escrevi sobre isto: a escolha do nome, a contenção na conceção do malware e a forma como os ataques se detinham sistematicamente antes de chegarem à exploração total. A minha interpretação é que o Shai-Hulud não era, essencialmente, uma operação criminosa. Era uma mensagem — de alguém que compreendia o ecossistema suficientemente bem para saber exatamente quais os pontos de pressão que o fariam reagir.

Os Fremen rezam para que a passagem do Criador purifique o mundo. O agressor parece ter chegado a uma conclusão semelhante: só a dor visível obrigaria o ecossistema a confrontar aquilo que tornou o verme possível. Para os Fremen, Shai-Hulud não é simplesmente um animal destrutivo. É o Criador. A sua passagem rasga o deserto, mas também purifica e impõe as leis segundo as quais tudo nesse ecossistema deve viver.

Não se limitaram a libertar o Shai-Hulud.

Eles decidiram interpretar o Andarilho que compreendia por que razão ele tinha de vir.

Por que é que ainda não resolvemos o problema?

O aviso foi emitido. O ecossistema não reagiu com a rapidez necessária. O manual de estratégias do Shai-Hulud, disponibilizado em código aberto, foi então adotado por agentes sem qualquer interesse em transmitir uma mensagem — a TeamPCP, a Sapphire Sleet e outros que se concentraram diretamente no roubo de credenciais, nas carteiras de criptomoedas e no acesso remoto. Estruturas como a Mastra tornaram-se vítimas. O worm que começou por ser uma demonstração tornou-se um modelo a seguir.

O mais frustrante é que o obstáculo não é uma dificuldade técnica. O Trusted Publishing é gratuito e demora dez minutos. O obstáculo reside no facto de o custo de não o fazer ainda não ter recaído sobre a pessoa certa. Os mantenedores assumem o risco de reputação se o seu pacote for comprometido, mas o dano efetivo recai a jusante sobre equipas que não escreveram uma única linha do pacote afetado. Esse desalinhamento é estrutural. Os ataques fazem com que a adoção aumente temporariamente, depois a urgência desvanece-se e a próxima leva de pacotes volta a utilizar tokens de longa duração por defeito.

Olha para o gráfico. Os picos são reais. O mesmo se passa com a queda entre eles.

E o Mini Shai-Hulud acrescentou uma nova complicação: mesmo os pacotes que adotaram o Trusted Publishing podem ser comprometidos se o pipeline de CI subjacente não estiver reforçado. Extrair um token OIDC da memória do executor é mais difícil do que roubar um segredo armazenado. Mas não é impossível, e o ataque tem agora uma prova de conceito pública. O Trusted Publishing elimina um vetor de ataque. Não os elimina a todos.

A lacuna em matéria de responsabilização e o que fazer a esse respeito

A Axios registava mais de 100 milhões de downloads semanais e ainda não tinha adotado o Trusted Publishing antes de a Coreia do Norte ter comprometido o sistema. Alguém poderia ter apresentado um pedido de correção (PR) um ano antes. Ninguém o fez.

É essa a lacuna de responsabilização. A comunidade de segurança publica alertas, redige análises pós-incidente e espera que o próximo ataque faça a diferença. Existe uma versão mais construtiva dessa mesma pressão: abordar de forma proativa os 40 000 pacotes que ainda não fizeram a transição, tal como a Let's Encrypt abordou o HTTP. Enviar PRs. Abrir tickets. Identifique os pacotes mais descarregados que ainda utilizam tokens de longa duração. Faça com que o custo social de não adotar o TP seja superior aos dez minutos que demora a corrigir o problema.

É deste tipo de ativismo que o ecossistema precisa realmente. Não de mais um aviso da CISA. Não de mais um artigo de blogue que é lido e depois esquecido. É de uma pressão específica, direcionada e incómoda sobre os responsáveis específicos por pacotes específicos — aqueles com mais de 10 milhões de downloads semanais que estão a apenas uma credencial roubada de se tornarem o próximo incidente.

O setor da segurança já sabe qual é a solução há três anos. A questão é se estamos dispostos a tornar socialmente inaceitável ignorá-la.

40 000 dos 51 000 pacotes mais populares ainda não mudaram

11 001 pacotes adotaram o Trusted Publishing. Esses 11 mil representam cerca de 25 % do volume total de downloads, uma vez que alguns dos maiores pacotes fizeram a transição após cada onda de ataques. No entanto, isso significa que 40 369 pacotes (75 % do volume de downloads) continuam a ser publicados com tokens de longa duração.

Se manténs um pacote npm, vai fazê-lo agora. A documentação está aqui. São quatro linhas de YAML e uma caixa de seleção. Depois, certifica-te de que os teus fluxos de trabalho do GitHub Actions não têm `pull_request_target` sem limites de confiança explícitos; esse foi o vetor que o Mini Shai-Hulud utilizou para extrair o token OIDC, mesmo depois de o TP estar implementado.

Se dependeres de pacotes que ainda não foram atualizados, abre um ticket. Envia um PR. O responsável pela manutenção pode não saber que o Trusted Publishing existe, ou pode simplesmente precisar que alguém faça com que a inação pareça mais incómoda do que a correção de dez minutos.

O verme da areia em «Dune» chama-se Shai-Hulud, o que significa «o grande ancião do deserto». Os Fremen não comemoram quando ele destrói algo. Compreendem que a sua passagem molda o ecossistema de formas que nada mais consegue.

Essa é a verdade incómoda que está no cerne deste artigo. Os ataques surtiram efeito. A dor teve um impacto que três anos de alertas não conseguiram ter.

Aprendemos a lição. O ecossistema reage à pressão, e essa pressão não tem de vir necessariamente de um verme. O Wanderer compreendeu por que razão o Criador teve de vir. Estamos a trabalhar para que o próximo não seja necessário.

Em breve, mais informações sobre isso.

Compartilhar:

https://www.aikido.dev/blog/shai-hulud-trusted-publishing

Assine para receber notícias

4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes

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.