+− THE DAILY DIFFdev & AI news
SHIP IT

Uma atualização do Dependabot publicou um worm. 22 pacotes.

Um bot abre um pull request.

Um bot abre um pull request. Um humano o mescla 24 minutos depois. 95 minutos depois disso, um worm publicou 110 versões maliciosas de seus 22 pacotes npm, em seu nome, com um token que encontrou em seu CI.

Leia a edição escrita (Inglês) ↗

O que este vídeo aborda

  • Um bot, um humano, um worm
  • Como aconteceu, por que o npm permitiu, quem é o culpado
  • Cronologia: o cache envenenado
  • 21:48 — a atualização do Dependabot
  • Por que funciona

Transcrição traduzida

Traduzido da narração original em inglês. Áudio e legendas disponíveis são controlados pelo YouTube.

Um bot, um humano, um worm

0:00 Um bot abre um pull request; um humano o mescla vinte e quatro minutos depois. Noventa e cinco minutos depois, um worm publicou cento e dez versões de seus pacotes, como ele. A análise post-mortem do TanStack tem os carimbos de data/hora upstream, o mantenedor downstream tem o resto, e o Hacker News dá mil e cem pontos e um nome: Mini Shai-Hulud. Como acontece, por que o npm permite, quem é o culpado.

Como aconteceu, por que o npm permitiu, quem é o culpado

0:21 Este é o The Daily Diff, post-mortem. 11 de maio, manhã. Um fork renomeado abre um pull request contra o TanStack Router. Ele fecha dentro de uma hora, mas um fluxo de trabalho de benchmark já executou seu código e

Cronologia: o cache envenenado

0:33 salvou um cache envenenado sob a chave que o fluxo de trabalho de release usará. Dezenove e vinte. Uma mesclagem legítima executa o release. O cache retorna, um binário lê a memória do runner, pega o token de publicação e envia oitenta e quatro versões em quarenta e dois pacotes, com proveniência válida. Os testes falham. Ele publica mesmo assim. Dezenove e quarenta e seis, um pesquisador da StepSecurity registra o problema; às nove UTC tudo é descontinuado e o aviso é emitido.

0:55 Descontinuado não significa removido: o npm se recusa a despublicar qualquer coisa com dependentes, então ele permanece instalável por horas. Vinte e uma e quarenta e oito. Em um projeto de dados de aviação de nove estrelas, o Dependabot abre seu pull request de rotina: atualize o grupo de dev-dependencies, treze atualizações. Duas são versões envenenadas do TanStack. Vinte e duas e doze: mesclado. O fluxo de trabalho de publicação executa o npm C-I com o token em

21:48 — a atualização do Dependabot

1:15 escopo; um script prepare o lê, e às vinte e duas e dezessete o worm publica como ele. Cinco versões de cada pacote que o token alcança, até mesmo um antigo projeto paralelo: um token clássico para tudo. Cento e dez versões em noventa e cinco minutos. Ele descobre por e-mail, depois da meia-noite. Por que funciona. Um: npm install executa scripts de ciclo de vida de estranhos por padrão, e o script prepare de uma dependência git conta.

1:39 Dois: o worm quer uma coisa: um token que publica sem segundo fator. Então ele pergunta ao registro o que mais aquele mantenedor possui, e republica tudo com ele mesmo dentro. Três: nada na cadeia é uma pessoa.

Por que funciona

1:51 Um bot propõe, um pipeline instala, e o worm retribui o favor: seus ramos de "dead-drop" são nomeados dependabot slash github-actions slash fremen. git blame. Modelo de instalação do npm, cinquenta e cinco por cento: scripts executados na instalação, depreciado permanece instalável, existem tokens que ignoram o segundo fator. CI do TanStack, vinte e cinco: um fluxo de trabalho de pull request target não auditado executando código de fork com acesso de gravação ao cache. O hábito de atualizar, quinze: treze atualizações mescladas em vinte e quatro minutos, token na sala.

2:17 Dependabot, cinco: tão confiável que o worm veste seu uniforme.

git blame

2:20 Raio de impacto: quarenta e dois pacotes TanStack. Vinte e dois downstream, de um projeto com nove estrelas. Mais de cento e sessenta em todo o ecossistema assim que o worm atinge o Mistral. Cada versão upstream carregava uma assinatura válida: construída pelo pipeline oficial. Verdadeiro. Veredito, post-mortem: SHIP IT. Ambos os mantenedores postam post-mortems com carimbo de data/hora dentro de um dia; dentro de três, o pipeline downstream instala com ignore-scripts, separa a compilação da publicação e descarta o token de longa duração.

Raio de impacto

2:47 Os padrões do npm não mudaram. Segunda-feira: ignore-scripts na instalação, e o token de publicação fora do trabalho que o executa. Envie-me o incidente sobre o qual você ainda não tem permissão para falar, nos comentários, ou em thedailydiff.dev. E essa é a diferença de hoje.

Veredito

3:00 Eu sou o Niko da Axrisi. Mescle com responsabilidade.

Fontes

  1. TanStack postmortem (Tanner Linsley, May 11, refined May 15)tanstack.com
  2. TanStack "Hardening TanStack After the npm Compromise" (May 12)tanstack.com
  3. TanStack/router#7383 — the StepSecurity detection issuegithub.com
  4. Downstream incident post, @squawk/* (May 12)github.com
  5. Downstream hardening post (May 14)github.com
  6. The Dependabot PR #246 (opened 21:48 UTC, merged 22:12)github.com
  7. @tan_stack advisory post, 21:19 UTCx.com
  8. StepSecurity — worm internals, bypass_2fa search, Dependabot-style branch nameswww.stepsecurity.io
  9. Socketsocket.dev
  10. Aikido — "over 160 packages, including Mistral"www.aikido.dev
  11. Hacker News (1,097 points)news.ycombinator.com

Vídeos relacionados