TanStack e MUITOS outros pacotes afetados - análise detalhada
MMaximilian Schwarzmüller
컴퓨터/소프트웨어경제 뉴스AI/미래기술
Transcript
00:00:00Temos outro grande, um ataque à cadeia de suprimentos realmente grande acontecendo agora e ainda está em andamento
00:00:06e se espalhou do NPM também para o ecossistema Python, então talvez agora não instale nenhum
00:00:12pacote NPM ou Python. E certifique-se de que seu sistema esteja configurado com segurança em geral. Tenho outro vídeo
00:00:19sobre isso, compartilharei um link abaixo e voltarei a esse assunto aqui neste vídeo também, mas primeiro quero
00:00:23dar alguns detalhes sobre o que foi afetado e como descobrir se você foi afetado. Tudo começou com os
00:00:30pacotes TanStack: TanStack query, TanStack router, TanStack start e assim por diante. Ontem, 11 de maio,
00:00:36em um curto espaço de tempo, alguns pacotes maliciosos ou, na verdade, todos os pacotes TanStack foram
00:00:43publicados com versões maliciosas e isso foi contido rapidamente em 20 minutos. No final,
00:00:50foi detectado e contido rapidamente, mas todos esses pacotes maliciosos foram publicados naquele
00:00:57intervalo ou naquele curto espaço de tempo aqui. E então continuou se espalhando e ainda está
00:01:03se espalhando. Espalhou-se para os pacotes Mistral que, ha ha, só têm quatro usuários, mas ainda assim foram
00:01:09afetados porque este malware age como um verme e rouba dados, rouba credenciais, também potencialmente
00:01:16as suas, se estiver instalado no seu sistema. Voltarei a como descobrir se você foi afetado em apenas
00:01:20um segundo, mas ele continuou se espalhando para mais pacotes NPM, porque essa é a ideia por trás dele, e
00:01:26depois até para o ecossistema Python, e isso está acontecendo agora. Isso tem apenas algumas horas,
00:01:32duas horas no momento em que estou gravando isto. Agora, como você descobre se foi
00:01:39afetado? Se você instalou qualquer pacote TanStack ontem à noite, no meu caso aqui no fuso horário
00:01:45alemão, você deve se considerar afetado. Se você o instalou por volta desse horário, lembre-se
00:01:54de que é UTC, então você precisa traduzir isso para o seu fuso horário; nesse período, você deve se considerar
00:02:00afetado. Mas como ele está se espalhando para os pacotes Mistral, para muitos outros pacotes JavaScript,
00:02:06mais do que eu poderia listar aqui, você também deve considerar a si mesmo ou sua máquina afetados e comprometidos.
00:02:13E compartilharei links para essas postagens abaixo para que você possa se aprofundar e ver a lista completa
00:02:18de todos esses pacotes afetados conforme foram publicados. Mas, como mencionado, ainda está em andamento,
00:02:22então talvez não instale nada agora. Também existem indicadores de comprometimento. Você deve
00:02:31procurar por certos hashes de arquivo, hashes SHA, para o roteador em um arquivo JS. Também vincularei este post abaixo.
00:02:38E se você tiver uma maneira de monitorar quais solicitações de rede aconteceram em sua máquina,
00:02:42você deve procurar por tráfego de saída para este URL, o que seria outro indicador claro
00:02:48de que dados foram exfiltrados do seu sistema. O que significa comprometimento em detalhes? Significa que
00:02:55este malware faz principalmente duas coisas. A primeira coisa importante que ele faz é colher dados. Ele
00:03:03procura por tokens NPM, tokens GitHub, credenciais AWS e outros segredos. Ele verifica seu sistema em
00:03:12locais típicos onde você armazena credenciais e segredos, os coleta e os envia para
00:03:18este URL que mostrei. Portanto, ele rouba esses segredos. Mas não faz apenas isso. Como eu mencionei,
00:03:26ele age como um verme, então também usa esses tokens do GitHub que foram roubados. Por exemplo,
00:03:33ele os utiliza e os tokens NPM para publicar mais pacotes comprometidos. Se você for o mantenedor
00:03:40de outro pacote, ou se talvez você tenha um fluxo de trabalho CI/CD que rodou naquele período e que
00:03:46dependia de alguns pacotes TanStack, então, nesse fluxo CI/CD, os pacotes TanStack
00:03:53maliciosos e comprometidos foram baixados. O código malicioso pode ter sido executado ali. E então, naquele
00:04:00fluxo de trabalho, não na sua máquina, mas no fluxo, ele também poderia roubar certas credenciais
00:04:06para publicar uma versão maliciosa, uma versão comprometida do pacote que seu fluxo CI/CD
00:04:14estava tentando construir. É assim que ele se espalha. Como mencionei, ele age como um verme. Ele usa esses
00:04:20tokens e credenciais roubados para publicar mais pacotes comprometidos. E é assim que ele se espalha
00:04:26para o Mistral, depois para outros pacotes JavaScript e, em seguida, até para o ecossistema Python. E é
00:04:32onde estamos agora. E ainda está se espalhando, até onde eu sei. Agora, como você pode se proteger
00:04:39contra isso? Criei um vídeo sobre isso no meu outro canal, AkataMind. Também o vincularei abaixo.
00:04:44Resumindo, você quer ter certeza de que executa seu código ou faz seu desenvolvimento,
00:04:51não diretamente na sua máquina host, se possível, mas em alguma máquina virtual ou container de desenvolvimento,
00:04:57algo desse tipo. Você não quer armazenar segredos brutos na sua máquina. Quero dizer, para a AWS,
00:05:03por exemplo, você deve usar a abordagem de single sign-on em vez de armazenar credenciais IAM na
00:05:10sua máquina, por exemplo, e usar técnicas semelhantes para outros serviços que você possa usar. Além disso,
00:05:16você também deve considerar o uso de serviços como InPhysical ou Doppler para armazenar seus segredos
00:05:25na nuvem e não no seu disco rígido, nem em arquivos .env. Isso é algo que você pode querer fazer.
00:05:30E, novamente, falo sobre essas coisas naquele vídeo. E você também quer usar gerenciadores de pacotes
00:05:38e configurações que permitam configurar coisas como a idade mínima de lançamento, como o Bun permite
00:05:44que você faça. No arquivo bunfig.toml, você pode definir uma idade mínima de lançamento, o que garante que,
00:05:49mesmo se você rodar o bun install, você só instale pacotes que tenham pelo menos X segundos ou X dias de vida,
00:05:56neste caso aqui deste exemplo. O pnpm tem um recurso semelhante. As versões mais recentes do npm têm um
00:06:02recurso parecido. Novamente, cobri isso naquele outro vídeo. E se você usar algo como o Bun ou se tiver
00:06:09a configuração correta para o npm — mas o Bun faz isso por padrão, por exemplo — ele também bloqueia a
00:06:15execução de scripts post-install, por exemplo, que são scripts de ciclo de vida dos pacotes que você está
00:06:21instalando, o que oferece outro mecanismo de segurança porque esse malware geralmente depende
00:06:28de que tais scripts sejam executados no seu sistema. Portanto, usar um gerenciador de pacotes seguro e/ou uma
00:06:36configuração segura para ele, rodar seu código em uma máquina virtual ou container de desenvolvimento
00:06:41e não armazenar segredos em texto puro no seu sistema. É isso que você deve fazer em geral, mas agora talvez
00:06:46ainda mais, porque ataques como estes se tornarão cada vez mais sérios, e vamos analisar como esse ataque
00:06:52funcionou, porque é realmente interessante. Mas, claro, estamos tendo mais
00:06:58deles. Faço um vídeo como este quase todo mês agora, ou talvez até com mais frequência, porque, primeiro,
00:07:04acredito que eles estão mais fáceis de realizar. Agora, na era da IA, é mais fácil analisar os pacotes ou
00:07:12as dependências que você quer atingir e analisar seu código-fonte ou configuração de CICD para potenciais
00:07:22vetores de ataque. Foi o que aconteceu aqui com o TanStack. Não foi como se a máquina de um mantenedor
00:07:28tivesse sido afetada, mas sim o fluxo de trabalho CICD do TanStack que foi atacado. E eu
00:07:34voltarei a isso. Portanto, é mais fácil procurar vulnerabilidades com IA. É mais fácil escrever código,
00:07:40incluindo código malicioso, é claro. E ao mesmo tempo, temos essa explosão de software. Temos mais
00:07:45software sendo escrito do que nunca. Portanto, há mais alvos por aí, incluindo muitos alvos
00:07:51que talvez não se preocupem muito com segurança. Isso torna esses ataques mais interessantes também.
00:07:57Agora, como tudo isso começou? É realmente interessante. Como eu mencionei, não é uma abordagem nova,
00:08:03não é algo que nunca vimos antes, mas ainda assim bastante elaborada. A equipe do TanStack publicou um
00:08:09post-mortem, um artigo onde explicam como o ataque aconteceu. E também vincularei isso abaixo.
00:08:15Mas, claro, darei o resumo aqui porque, no final, este ataque baseou-se em
00:08:22três etapas principais, que explicarei em detalhes. Um padrão de solicitação “pull request target pwn”. Vou
00:08:30explicar o que é isso. Depois, o envenenamento do cache do GitHub Actions através do limite de confiança baseado em fork
00:08:38e a extração de memória em tempo de execução de um token OIDC. Ok, o que tudo isso significa? Novamente,
00:08:45você pode ler o artigo para todos os detalhes, mas deixe-me dar o resumo. E vamos começar com
00:08:50o padrão de solicitação pwn de pull request. O que é isso? Para entender isso, temos que entender
00:08:58que o GitHub Actions é, obviamente, a solução de CICD, o produto de CICD do GitHub. E eu
00:09:05tenho um curso sobre GitHub Actions também, a propósito, se você quiser aprender como configurar o GitHub Actions,
00:09:10como usar o produto para tarefas de CICD, como publicar seus pacotes ou seu site e assim por diante.
00:09:16Agora, como todas as ferramentas de fluxo de trabalho CICD, o GitHub Actions depende de eventos que acionam fluxos, porque,
00:09:24claro, CICD trata de fazer algo de forma automatizada. Por exemplo, lançar seu site,
00:09:29publicar, implantar seu site de forma automatizada quando você faz um push para a branch principal, por exemplo.
00:09:34Assim, você tem vários eventos que podem acionar um fluxo de trabalho, e o push é um deles, por exemplo,
00:09:40para que você possa dizer: ok, se eu fizer um push para a branch principal — você pode filtrar por
00:09:44diferentes branches — então quero executar certas tarefas. Quero instalar minhas dependências. Quero
00:09:49construir o projeto. Quero enviá-lo para o meu servidor. É isso que você poderia fazer. Agora, outro gatilho
00:09:56é o “pull_request_target”. Este gatilho é ativado se houver uma pull request aberta para o seu
00:10:05repositório. E isso, claro, significa que qualquer pessoa pode fazer um fork do seu repositório, fazer algo lá, dar um push
00:10:14em seu fork e então abrir uma pull request com o seu repositório. E isso acionaria
00:10:19este fluxo de trabalho. Parece perigoso? Bem, de certa forma é. E foi o que iniciou este ataque.
00:10:25Também existe o gatilho “pull_request”. Falei sobre o pull_request_target antes,
00:10:31mas também temos o pull_request, que funciona da mesma maneira, mas o pull_request executa o fluxo de trabalho
00:10:38CICD no contexto do repositório forkado. Portanto, qualquer coisa maliciosa que possa estar ocorrendo ali,
00:10:45acontece no repositório forkado, não no repositório base. Portanto, isso não é um problema.
00:10:52O pull_request_target, por outro lado, roda no contexto do repositório base. E isso, claro,
00:10:58é potencialmente perigoso. É potencialmente perigoso porque qualquer pessoa pode abrir uma pull request. E,
00:11:04claro, o que aconteceu neste caso do ataque ao TanStack foi que, naquela pull request, naquele
00:11:10fork, o invasor incluiu o código malicioso, o código do verme, o malware no repositório TanStack,
00:11:20no fork dele, mas o incluiu ali. Então o invasor abriu a pull request,
00:11:26e isso levou à execução do pull_request_target. E então, como mencionado, isso inicia um
00:11:33runner do GitHub Actions, que passa a rodar no contexto do repositório base. O que isso significa?
00:11:40Isso não significa que o invasor ganhe acesso ao código base ou possa mesclar o código malicioso
00:11:46no repositório, mas significa que, por exemplo, o cache que está sendo usado ali
00:11:53será compartilhado com as execuções subsequentes do GitHub Actions que partem do repositório base,
00:12:00potencialmente de hooks ou gatilhos de eventos totalmente diferentes, como o gatilho push.
00:12:05A próxima coisa que aconteceu foi o envenenamento do cache. Mas o que isso significa? Bem,
00:12:11o invasor adicionou código ao seu fork que garantiria que, quando o GitHub Action
00:12:17rodasse para o gatilho pull_request_target, ele executaria um comando, o comando hash files,
00:12:23que é suportado pelo GitHub Actions, para armazenar algo no cache do GitHub Actions. Agora,
00:12:28do que se trata esse cache? A ideia por trás do cache do GitHub Actions é simplesmente acelerar
00:12:33esses fluxos de trabalho. Assim, você pode, por exemplo, fazer o hash das dependências. A ideia é que,
00:12:39se uma dependência da qual seu pacote depende não mudou, por que você passaria por todo
00:12:46o processo de instalação novamente? Isso apenas consome tempo, e tempo é dinheiro, porque você é cobrado pelo
00:12:52tempo de execução do seu fluxo do GitHub Actions. E, claro, você não quer ter fluxos que
00:12:56levem uma eternidade. Portanto, na maioria dos fluxos, como ao construir os pacotes TanStack,
00:13:00você instala as dependências dos pacotes TanStack e depois faz a etapa de build e constrói
00:13:06seu pacote TanStack. Novamente, se as dependências do TanStack não mudaram,
00:13:12por que reinstalá-las? Essa é a ideia por trás do cache. E isso faz sentido. Claro, o problema é que,
00:13:18como essa execução do GitHub Actions de pull_request_target e outras execuções,
00:13:24como as do gatilho push, compartilham o mesmo contexto, elas compartilham o mesmo cache. E é
00:13:31aí que entra o envenenamento do cache, porque o invasor conseguiu armazenar uma versão maliciosa ou colocar
00:13:39aquele código malicioso em uma dependência do TanStack, por assim dizer, e salvar isso no cache. Então o invasor
00:13:46só teve que esperar por um fluxo de trabalho normal do GitHub Actions ser executado para os pacotes TanStack.
00:13:53Ou seja, que algum mantenedor desse um push em algum código, e então aquela outra execução do GitHub Actions reutilizaria
00:14:01o mesmo cache que foi configurado pela execução maliciosa anterior e agora puxaria o
00:14:08cache envenenado preparado, que incluía o código malicioso. Foi assim que o código malicioso
00:14:13passou do fork para a execução normal do GitHub Actions em um push normal de um mantenedor normal,
00:14:21que não havia sido afetado por nenhum código malicioso. Foi assim que o cache foi usado como um veículo
00:14:28de transporte entre essas duas execuções do GitHub Actions no final. E então, como um terceiro passo, assim que o
00:14:35código malicioso entrou em uma execução regular de um fluxo CICD do TanStack, por causa daquele evento
00:14:44de push, ele roubou um token NPM de curta duração, um token OIDC no final, para publicar uma versão maliciosa
00:14:54do pacote TanStack. Agora, a que estou me referindo aqui? O NPM tem esse recurso, que é chamado de
00:15:00publicação confiável (trusted publishing), que, em teoria, torna a publicação de pacotes NPM mais segura, porque
00:15:04existem basicamente duas maneiras de publicar um pacote no NPM, pode-se dizer. Uma é você criar um
00:15:11token com sua conta NPM e usá-lo para publicar novas versões do seu pacote. O problema
00:15:19é que, se esse token for roubado, qualquer pessoa poderá publicar uma nova versão desse pacote. Para aumentar a
00:15:26segurança, existe esse processo de publicação confiável onde o NPM diz: não, você não pode publicar pacotes da
00:15:33sua máquina, você tem que passar por um desses provedores confiáveis, sendo o GitHub Actions um
00:15:37deles, e há uma integração de publicação confiável para o GitHub Actions que você pode configurar. E então,
00:15:44como parte desse processo, um token de publicação de curta duração será recuperado
00:15:50ou será solicitado. E então esse token de curta duração será usado para assinar aquela nova versão
00:15:57do pacote que está sendo publicada. Portanto, em teoria, a ideia é que o token seja difícil de roubar porque
00:16:03não está na máquina de nenhum mantenedor. E, além disso, é de curta duração. Mesmo que fosse roubado,
00:16:08não ficaria ativo por muito tempo. O problema, claro, é que se o código que roda no fluxo
00:16:15de trabalho CICD que solicitou aquele token confiável tiver sido afetado, então aquele código
00:16:21malicioso terá acesso a este token de publicação confiável novinho e de curta duração. E foi o que aconteceu
00:16:27aqui. Assim, aquele código malicioso abusou desse token ou o usou para publicar uma nova versão
00:16:36do pacote TanStack. Agora, curiosamente, este ataque na verdade falhou um pouco porque ele
00:16:44obteve aquele token confiável e o usou para entrar em contato com a API do NPM para publicar uma nova versão
00:16:52do pacote TanStack que incluía este verme, que incluía o código malicioso. Mas ele acabou
00:16:58caindo em um fluxo de trabalho do GitHub Actions que não conseguiu ser concluído porque havia algo errado
00:17:06no código que foi enviado para o CICD. Portanto, se os invasores tivessem prestado atenção para executar seu
00:17:12ataque em um momento em que um código válido estivesse sendo enviado, então, é claro, este fluxo teria sido
00:17:19concluído e eles não teriam que depender da publicação manual de um pacote malicioso entrando em contato
00:17:26com a API do NPM; em vez disso, poderiam ter injetado o código malicioso neste fluxo, como
00:17:32fizeram, deixado este fluxo terminar com sucesso e então uma versão comprometida do TanStack teria
00:17:38sido publicada parecendo muito válida, pois foi um push normal de um mantenedor e o fluxo
00:17:45terminou com sucesso. A maneira como este ataque funcionou, porque aquele fluxo de trabalho não terminou com sucesso,
00:17:51tornou um pouco mais fácil capturar o que estava acontecendo por um colaborador externo aqui no final,
00:18:00porque você podia ver que uma nova versão dos pacotes TanStack foi publicada, embora o
00:18:05fluxo de trabalho do GitHub Actions tenha falhado, então nenhuma nova versão deveria ter sido publicada. Assim, era possível ver uma
00:18:12discrepância ali, o que tornou um pouco mais fácil detectar esse ataque, o que é uma parte onde os
00:18:19mantenedores do TanStack e todos nós tivemos sorte. No entanto, foi um ataque bastante elaborado, como você
00:18:26provavelmente pode notar, que funcionou totalmente sem comprometer a máquina de ninguém e, embora tenha sido pego
00:18:32rapidamente, causou danos sérios porque, como mencionei, ainda está se espalhando. E este foi um longo
00:18:41episódio sobre tudo isso, eu sei, mas eu realmente quero enfatizar: você tem que trabalhar para tornar seu sistema
00:18:49seguro, como compartilhei antes, como compartilho neste vídeo; você quer ter certeza de que reduz o
00:18:56perigo de ser afetado. Este ataque, repito, foi pego rapidamente e, no entanto, ainda está se espalhando,
00:19:05então ainda não acabou. E é possível que nem todos os ataques sejam pegos tão rapidamente
00:19:11no futuro; como mencionei, eles tiveram um pouco de sorte aqui, poderia ter sido mais difícil detectar este
00:19:18ataque, então talvez o dano fosse ainda maior. Mas já é bastante grande aqui e
00:19:24ainda não acabou. E veremos mais ataques desse tipo, tenho certeza, porque, como mencionei, a superfície de ataque
00:19:31está ficando maior e mais interessante; há mais pessoas escrevendo código, muitas pessoas que
00:19:36não sabem o que estão fazendo e a IA ajuda na execução de tais ataques. Então, sim, é isso que está acontecendo
00:19:42agora. Se não for necessário, talvez não instale nada; verifique novamente sua configuração e você
00:19:48encontrará todos os links abaixo se quiser se aprofundar, se quiser ver a lista completa de pacotes afetados
00:19:51e assim por diante.
Community Posts
No posts yet. Be the first to write about this video!
Write about this video