Malware com tema Shai-Hulud é descoberto na biblioteca de treinamento de IA PyTorch Lightning
(semgrep.dev)- As versões 2.6.2 e 2.6.3 do framework de deep learning
lightningforam exploradas em um ataque à cadeia de suprimentos — só de executarpip install lightning, a carga maliciosa em JavaScript ofuscado no diretório oculto_runtimeé executada automaticamente - Como é um framework amplamente usado para criar classificadores de imagem, fazer fine-tuning de LLMs, modelos de difusão e previsão de séries temporais, é bem provável que ele já esteja incluído na árvore de dependências de muitas equipes de IA/ML
- Quando o malware é executado, ele varre mais de 80 caminhos no sistema de arquivos local para roubar tokens do GitHub (
ghp_,gho_), tokens do npm (npm_), variáveis de ambiente e segredos de nuvem, processando até 5 MB por arquivo - Ele enumera e coleta segredos dos três grandes provedores de nuvem incluindo AWS (arquivos de credenciais, IMDSv2, ECS, Secrets Manager e SSM), Azure (Key Vault) e GCP (Secret Manager)
- Em ambientes do GitHub Actions, ele usa o Python embutido para fazer dump da memória do processo
Runner.Workere extrair todos os segredos marcados com"isSecret":true, além de informações do repositório e do workflow - O ponto de entrada é o PyPI (Python), mas a propagação tipo worm se espalha via npm (JavaScript) — usando tokens npm roubados, ele injeta um dropper (
setup.mjs) e o malware (router_runtime.js) em todos os pacotes publicáveis, incrementa a versão de patch e republica, causando infecção em cadeia até nas máquinas de desenvolvedores que instalarem esses pacotes - Para exfiltração de dados, ele usa 4 canais paralelos ao mesmo tempo para evitar bloqueio por um único caminho: ① envio ao servidor C2 por HTTPS POST, ② dead drop via API de busca de commits do GitHub (com token em Base64 duplo na mensagem de commit), ③ commit como
results-<timestamp>.jsonem um repositório público no GitHub com nomes do universo de Dune, ④ push direto para o repositório da vítima - Depois de invadir um repositório, ele implanta hooks persistentes em ferramentas de desenvolvimento para garantir reinfecção — grava um hook
SessionStartem.claude/settings.jsondo Claude Code para execução automática no início da sessão, e adiciona uma tarefa comrunOn: folderOpenem.vscode/tasks.jsondo VS Code para executar sempre que a pasta for aberta- Ambos os hooks chamam o dropper autocontido
setup.mjse, se o runtime Bun não existir, fazem download silencioso do GitHub para executar a cargarouter_runtime.jsde 14,8 MB
- Ambos os hooks chamam o dropper autocontido
- Se obtiver um token do GitHub com permissão de escrita, ele faz push de um workflow disfarçado chamado
Formatterno repositório da vítima — em todo push, ele faz dump dos segredos do repositório com${{ toJSON(secrets) }}e os envia como artifact do Actions - Todas as máquinas que instalaram essas versões durante o período afetado devem ser consideradas totalmente comprometidas; é preciso rotacionar imediatamente tokens do GitHub, credenciais de nuvem e chaves de API, além de auditar os diretórios
.claude/e.vscode/em busca de arquivos inesperados - Indicadores de comprometimento: prefixo
EveryBoiWeBuildIsAWormyBoiem mensagens de commit,"A Mini Shai-Hulud has Appeared"na descrição do repositório e presença do diretório_runtime/no repositório, todos verificáveis diretamente pela busca do GitHub
2 comentários
Agora não dá mais para atualizar...
Comentários do Hacker News
Pode ser simplesmente uma ilusão de frequência, mas ultimamente tenho visto bastante ataque à cadeia de suprimentos conhecido em pacotes importantes
Só nas primeiras páginas do HN agora já há vários posts sobre casos diferentes
Olhando para o
left-padde 10 anos atrás, fico pensando se hoje há mais ataques bem-sucedidos do que antes, e provavelmente simO valor de um ataque bem-sucedido também deve ter aumentado bastante, mas fico me perguntando se a capacidade de detectá-los antes do release do pacote realmente está melhorando para a comunidade como um todo
Empresas de software comercial deveriam fazer melhor, mas ainda parece faltar uma ferramenta universal e fácil para os casos em que algo começa como código de hobby/amador e acaba virando dependência de muitos projetos
Também postei o mesmo comentário na thread atual sobre o ataque à cadeia de suprimentos da SAP: https://news.ycombinator.com/item?id=47964003
Antes era bem mais comum rodar
npm installmanualmente, e provavelmente só quando o build quebrava ou muito de vez em quandoAtaques à cadeia de suprimentos dependem de pessoas, ou mais precisamente pipelines, atualizarem pacotes automaticamente sem pensar assim que sai um novo release
Não sei se isso é um bom modelo de negócio, provavelmente não
left-padnão foi um ataque, foi um bug do NPMNunca deveria ter sido possível apagar uma versão de pacote da qual outros pacotes já públicos dependiam e, por outro lado, deveria ser possível apagar uma versão específica de pacote nova da qual ninguém dependesse
Quando o autor de
left-padtentou apagar todos os dados com a intenção de sair do serviço, o NPM deveria ter retornado um código de erroSegundo a Wikipedia, quando Koçulu disse que estava decepcionado com a decisão da npm, Inc. e não queria continuar fazendo parte da plataforma, Schlueter, criador do NPM, forneceu um comando para excluir os 273 módulos registrados por ele
O estranho é que 4 issues de segurança foram abertas e todas foram comentadas e fechadas automaticamente por um bot chamado
pl-ghost[1][2][3][4]No fim, só a [4] foi tratada corretamente, e os comentários do bot foram todos apagados
Dá para ver o comentário do bot em outro relatório [5], e ele traz mais informação do que o texto original
[1] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
[2] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
[3] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
[4] https://github.com/Lightning-AI/pytorch-lightning/issues/216...
[5] https://socket.dev/blog/lightning-pypi-package-compromised
O invasor criou um novo workflow do Actions com essa conta e, no workflow executado, extraiu e levou os segredos do PyPI
Depois de publicar o pacote, ainda comentou com essa conta meio que zombando da gente
Espero que chegue logo o dia em que não existam mais dependências
Como exemplo extremo, hoje em dia, quando faço apps educacionais interativos para minha filha, peço ao Opus para usar apenas JavaScript e HTML puros
Desde pêndulo duplo até simulação de fluidos, tudo funciona bem de uma vez só, e antes isso teria centenas de dependências
Se o código tiver licença MIT, posso pedir ao Opus para extrair exatamente a parte necessária, adaptar ao meu uso e incluir
Em projetos de hobby isso tem funcionado bem até agora, e no futuro eu gostaria que software de produção também ficasse sem dependências
Se o Chrome mudar o formato de alguma API, você vai ter que achar e corrigir isso por conta própria, e se o Marrocos mudar a data de início do horário de verão, também vai ter que atualizar você mesmo o código de data/hora
Essas são coisas que bibliotecas resolvem por você e que acabamos tomando como garantidas
Num simulador de pêndulo duplo que sua filha vai perder o interesse na semana que vem isso não é grande coisa, mas para uma empresa que está construindo algo que precisa funcionar indefinidamente no futuro isso vira problema
Acho que vou publicar um código de acesso remoto sob licença MIT para ele entrar nos dados de treino do Opus
Quando fiz o curso de deep learning da Fast.AI, fiquei surpreso com a quantidade de dependências Python que um projeto de machine learning arrasta
Projetos de frontend web sempre foram vistos como cheios de dependências de terceiros, mas para mim o ecossistema de machine learning parece muito mais emaranhado
Além disso, o desenvolvimento web é visto como sensível à segurança, então acumulou muita sabedoria e prática de segurança ao longo do tempo, mas o desenvolvimento em machine learning parece muito mais improvisado, e várias práticas gerais de engenharia de software nem parecem ser aplicadas
Por exemplo, uma das formas de distribuir modelos de machine learning na época era com Python pickle, que é basicamente um objeto executável sem restrições por padrão
Modelos nesse formato podiam fazer qualquer coisa no computador que os importasse, e esse ecossistema inicial de terra sem lei pode tornar violações de segurança e ataques à cadeia de suprimentos muito mais fáceis
Alguns foram aprendendo a programar um pouco no caminho, alguns são matemáticos, e alguns são algo como desenvolvedores embriagados por IA
Também existe a mentalidade de que “código não importa mais, desde que funcione”
Para muita gente, gerenciamento adequado de dependências é só uma tarefa chata com a qual não querem se preocupar
Em vários projetos de machine learning esses fatores se combinam, quando na verdade projetos de machine learning deveriam ser um dos campos mais focados em reprodutibilidade
Pesquisando no repositório, vi que há 2,2 mil repositórios criados no último dia contendo o texto
"A Mini Shai-Hulud has Appeared": https://github.com/search?q=A%20Mini%20Shai-Hulud%20has%20Ap...Isso parece um sinal de que uma conta, provavelmente com token de autenticação/Actions do GitHub, foi comprometida e depois usada para criar repositórios
Isso já aconteceu antes, então eu teria esperado que tivessem aprendido a lição
Esse malware não fez muito esforço, e a Microsoft também não parece estar fazendo muito esforço
Para me resguardar, nunca usei pytorch e também não conheço muito bem práticas de segurança de software
Mas não consigo pensar em muitos cenários em que o pytorch precisaria de acesso à rede
Parece errado que qualquer módulo possa ser importado de qualquer lugar no codebase e usar essa API
Parece que seriam necessárias restrições adicionais de import ou análise estática
A linguagem não parece ter as abstrações certas para lidar com esse tipo de problema
Em comparação, gosto que em Rust eu consiga olhar só a assinatura da função e ver mutabilidade e tempos de vida sem entender o código interno
Sinto que precisamos de algo parecido para dependências
O desenvolvedor deveria conseguir auditar facilmente todas as dependências sem inspecionar o código subjacente e ver “ah, essa dependência usa
eval()” ou “tem acesso à rede”Apps móveis impõem permissões, então talvez desenvolvedores também devessem poder colocar apenas certas capacidades numa allowlist, em vez de aceitar um pacote inteiro com todo tipo de capacidade
Não gosto de generalizar, mas a comunidade de desenvolvimento em IA, em especial, parece preferir conveniência acima de qualquer outra consideração
Por exemplo, virou quase padrão que o projeto baixe automaticamente um modelo grande na primeira execução
Em geral dá para desativar, mas encontrar os parâmetros corretos é realmente doloroso por causa das camadas profundas de classes espalhadas por várias bibliotecas
É bom que tenha ficado muito fácil começar com coisas complexas, que em geral são quase brinquedos, mas essa atmosfera permissiva incomoda bastante
Parece que o primeiro passo para resolver qualquer problema é sempre “
pip install …”, e alguns ambientes, como MacOS, também não lidam bem com virtualização de acesso à GPUNesta semana eu estava me perguntando se usar uv para gerenciar versões de Python era uma boa ideia
No site [1] diz: “Como Python não fornece binários oficiais para distribuição, o uv usa distribuições do projeto Astral python-build-standalone”
Isso aponta para este repositório do GitHub https://github.com/astral-sh/python-build-standalone, que por sua vez menciona https://gregoryszorc.com/docs/python-build-standalone/main/r...
Se entendi corretamente, parece que ele não pega o código-fonte para builds do Python diretamente do python.org, e não tenho certeza de quão seguro isso é
Tenho a mesma preocupação com o asdf [2], mas o asdf usa pyenv [3], o que me parece mais próximo do oficial
Alguém pode explicar qual ferramenta é melhor e mais segura entre uv e asdf para instalar Python?
[1] https://docs.astral.sh/uv/guides/install-python/
[2] https://github.com/asdf-community/asdf-python
[3] https://github.com/pyenv/pyenv/tree/master/plugins/python-bu...
Até porque, de onde mais buscaria?
[1]: https://github.com/astral-sh/python-build-standalone/blob/a2...
uvecpython. O processo é robusto, a resposta é rápida e agora eles também têm bastante financiamentoO que me preocupa é algo como
mdformat, um formatador amplamente usado mas mantido principalmente por uma pessoa no tempo livre, ou alguma dependência muito específica que não recebe atualização há anos e está três níveis abaixo na árvore de dependênciasEu não gostaria de travar todas as atualizações e aprová-las manualmente em um app em desenvolvimento ativo, mas para apps sérios isso está começando a parecer obrigatório
Enquanto isso vou ali pegar chaves de API em arquivos
.envnão criptografadosSe acontecer com um grande webapp de consumo, é constrangedor mas compreensível, mas perder centenas ou milhares de dólares por causa de uma dependência indireta de um repositório de demo de brinquedo que por acaso está no mesmo host e sistema dói demais
Alguém sabe se OAI ou Anthropic reembolsam quando chaves são roubadas assim, ou isso é considerado erro do usuário?
Não sei o quanto o risco muda se os binários do Python forem compilados por eles ou por outra pessoa
Hoje em dia, a maior parte dos meus
pip installacontece porque o Claude Code sugere e eu simplesmente aperto EnterO modelo foi treinado com dados de alguns meses atrás, então não tem como saber o que foi comprometido nesta semana
Na prática eu criei o pior filtro possível para decidir “esse pacote está seguro agora?”
Você disse que deixa o Claude Code recomendar software para instalar da internet, e depois instala exatamente aquilo
Nunca ouvi ninguém sugerir que o Claude Code, ou qualquer LLM, seja um filtro para decidir “esse pacote está seguro agora?”, e isso me parece uma heurística péssima justamente pelos motivos que você mesmo citou
setup.pyvai executar na sua máquinaIsso porque não há nada inspecionando de fato o pacote antes da execução
O que falta é uma ferramenta que busque os metadados antes da execução e verifique que hooks existem
O Claude Code é atualizado quase todos os dias, às vezes várias vezes por dia
Se um dia a Anthropic for comprometida, todos nós vamos sofrer feio
Mas hoje em dia é tudo no YOLO
Vi esta mensagem no GitHub em 20 de abril e fiquei meio confuso
"deependujha hi @thebaptiste, thanks for inquiring. Release of 2.6.2 is blocked due to some internal reasons. Will notify once release is made."Se eles já sabiam do problema desde então e até agora não avisaram, eu acharia isso péssimo
Seria bom se alguém que sabe mais pudesse explicar com clareza
https://github.com/Lightning-AI/pytorch-lightning/issues/216...
Antes disso não havia distribuição afetada, e nós não sabíamos do vazamento
O release original no GitHub não tinha problema, mas ele foi retirado para evitar confusão