1 pontos por GN⁺ 2 시간 전 | 1 comentários | Compartilhar no WhatsApp
  • Entre 2026-05-11 19:20~19:26 UTC, o invasor publicou 84 versões maliciosas em 42 pacotes npm @tanstack/
  • A cadeia de ataque combinou o “Pwn Request” de pull_request_target, envenenamento de cache do GitHub Actions e extração de token OIDC da memória do runner
  • O token npm e o workflow de publicação não foram roubados nem comprometidos; o malware fez POST direto no registry com privilégios de OIDC trusted publisher
  • Ao instalar versões afetadas, credenciais de AWS, GCP, Kubernetes, Vault, GitHub, npm e SSH podem ter sido expostas e precisam ser substituídas
  • Todas as versões afetadas foram marcadas como deprecated, a remoção dos tarballs foi iniciada com a equipe de segurança do npm, e a issue de rastreamento e o GitHub Security Advisory foram publicados

Visão geral do incidente

  • Entre 2026-05-11 19:20~19:26 UTC, o invasor publicou 84 versões maliciosas em 42 pacotes npm @tanstack/*
  • A cadeia de ataque combinou o padrão pull_request_target “Pwn Request”, envenenamento de cache do GitHub Actions atravessando a fronteira de confiança entre fork↔base e extração de token OIDC da memória de processo do runner do GitHub Actions
  • Foi confirmado que os tokens npm não foram roubados e que o próprio workflow de publicação no npm não foi comprometido
  • As versões maliciosas foram detectadas publicamente em menos de 20 minutos pelo pesquisador externo ashishkurmi, da stepsecurity
  • Todas as versões afetadas foram marcadas como deprecated, e a remoção dos tarballs do registry foi realizada em conjunto com a equipe de segurança do npm
  • Usuários que instalaram versões afetadas em 2026-05-11 devem substituir as credenciais de AWS, GCP, Kubernetes, Vault, GitHub, npm e SSH acessíveis a partir do host de instalação
  • A issue de rastreamento é TanStack/router#7383, e o GitHub Security Advisory é GHSA-g7cv-rxg3-hmpx

Escopo do impacto

  • Pacotes afetados

    • O escopo afetado abrange 42 pacotes e 84 versões, com 2 versões por pacote publicadas em um intervalo de cerca de 6 minutos
    • A lista completa está incluída na issue de rastreamento
    • As famílias de produtos confirmadas como não afetadas são @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store e o meta pacote @tanstack/start
    • @tanstack/start-* não está incluído na lista de itens confirmados como não afetados
  • Comportamento do malware

    • Quando um ambiente de desenvolvedor ou de CI executa npm install, pnpm install ou yarn install em uma versão afetada, o npm interpreta a entrada maliciosa de optionalDependencies e busca o commit órfão do payload na rede do fork
    • Em seguida, o script de ciclo de vida prepare é executado, e entra em ação o router_init.js ofuscado de cerca de 2,3 MB escondido dentro do tarball afetado
    • O script malicioso coleta credenciais de locais comuns, como AWS IMDS/Secrets Manager, metadados do GCP, token de service account do Kubernetes, token do Vault, ~/.npmrc, token do GitHub, CLI gh, .git-credentials e chave privada SSH
    • Os dados roubados são exfiltrados pela rede de upload de arquivos do Session/Oxen messenger, tendo como destinos filev2.getsession.org e seed{1,2,3}.getsession.org
    • Como essa rede é criptografada de ponta a ponta e não há um C2 sob controle do invasor, a única mitigação em nível de rede é o bloqueio de IP/domínio
    • A lógica de autopropagação enumera outros pacotes mantidos pela vítima com registry.npmjs.org/-/v1/search?text=maintainer:<user> e depois os republica usando o mesmo método de injeção
    • Como o payload é executado como parte do ciclo de vida do npm install, hosts que instalaram versões afetadas em 2026-05-11 devem ser tratados como potencialmente comprometidos

Linha do tempo

  • Antes do ataque: etapa de envenenamento de cache

    • Em 2026-05-10 17:16 UTC, o invasor criou github.com/zblgg/configuration, um fork de TanStack/router, e mudou o nome para evitar aparecer em buscas de lista de forks
    • Em 2026-05-10 23:29 UTC, o commit malicioso 65bf499d16a5e8d25ba95d69ec9790a6dd4a1f14 foi criado no fork com a identidade manipulada claude <claude@users.noreply.github.com>
    • Esse commit adicionou packages/history/vite_setup.mjs, um payload JS empacotado de cerca de 30.000 linhas, e incluiu [skip ci] na mensagem do commit para suprimir a CI do evento de push
    • Por volta de 2026-05-11 10:49 UTC, zblgg abriu o PR #7378 com o título “WIP: simplify history build” tendo como alvo a main de TanStack/router
    • bundle-size.yml e labeler.yml foram ambos executados automaticamente para o PR via pull_request_target, e pull_request_target contornava o gate de aprovação para primeira contribuição, então não foi necessária aprovação separada
    • pr.yml, que usa pull_request, ficou bloqueado aguardando aprovação e não foi executado
    • Entre 2026-05-11 11:01 e 11:11 UTC, zblgg fez vários force-pushes no head do PR, provocando execuções adicionais de pull_request_target
    • Em 2026-05-11 11:11 UTC, o commit malicioso 65bf499d foi colocado no head do PR, e o job benchmark-pr de bundle-size.yml fez checkout de refs/pull/7378/merge e depois executou pnpm install e pnpm nx run @benchmarks/bundle-size:build, momento em que vite_setup.mjs foi executado
    • Em 2026-05-11 11:29 UTC, um cache do GitHub Actions de 1,1 GB chamado Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11 foi armazenado em TanStack/router
    • Esse cache foi armazenado no escopo refs/heads/main e foi configurado para corresponder à chave que release.yml consultaria no próximo push para main
    • Em 2026-05-11 11:31 UTC, o invasor reverteu o PR para o HEAD da main naquele momento, b1c061af, fazendo o PR visível parecer um no-op de 0 arquivos; no mesmo minuto, fechou o PR e apagou a branch, mas o cache contaminado permaneceu
  • Disparo: etapa de publicação

    • Em 2026-05-11 19:15 UTC, Manuel fez merge do PR #7369, gerando um push para main, e a execução do workflow release.yml 25613093674 começou às 19:15:44 e depois falhou
    • Em 2026-05-11 19:20:39 UTC, o registro npm recebeu a publicação de @tanstack/history@1.161.9 e de outros 41 pacotes relacionados
    • No total, cerca de 84 versões foram publicadas em 42 pacotes, mas aproximadamente metade é visível exatamente neste segundo, enquanto o restante foi publicado na segunda execução
    • A autenticação da publicação foi feita por meio do OIDC trusted-publisher binding para TanStack/router release.yml@refs/heads/main, mas não ocorreu na etapa Publish Packages do workflow, que foi pulada por falha nos testes
    • O publicador real foi o malware executado durante a etapa de testes/limpeza, que gerou um token OIDC com a permissão id-token: write e fez POST diretamente para registry.npmjs.org
    • Em 2026-05-11 19:20:47 UTC, a execução 25613093674 foi concluída com status de failure
    • Em 2026-05-11 19:16 UTC, Manuel fez merge do PR #7382, causando um segundo push para main, e a execução do workflow 25691781302 começou às 19:16:22
    • A segunda execução também restaurou o mesmo cache contaminado e, em 2026-05-11 19:26:14 UTC, um segundo conjunto de versões por pacote, incluindo @tanstack/history@1.161.12, foi publicado pelo mesmo mecanismo OIDC
    • Em 2026-05-11 19:26:20 UTC, a execução 25691781302 também foi concluída com status de failure
  • Detecção e resposta

    • Por volta de 2026-05-11 19:50 UTC, o pesquisador externo carlini abriu a issue #7383 com a fingerprint maliciosa de optionalDependencies e a lista de pacotes
    • A lista inicial continha 14 dos 42, e o pesquisador também notificou diretamente a equipe de segurança do npm
    • Por volta de 2026-05-11 20:00 UTC, Manuel confirmou o incidente em #7383 e iniciou a resposta
    • Por volta de 2026-05-11 20:10 UTC, Manuel removeu a permissão de push no GitHub de outros membros da equipe como precaução contra possível comprometimento das máquinas dos usuários
    • Por volta de 2026-05-11 20:30 UTC, Tanner enviou a lista completa de IOCs e o pedido de remoção dos tarballs do lado do registro para security@npmjs.com e apresentou um relatório formal de malware via npm
    • Por volta de 2026-05-11 21:00 UTC, uma varredura completa dos 295 pacotes @tanstack/* confirmou o escopo como 42 pacotes e 84 versões
    • Tanner iniciou a depreciação no npm de todos os 84 pacotes afetados, e @tan_stack e os maintainers fizeram alertas públicos no Twitter/X, LinkedIn e Bluesky
    • Em 2026-05-11 21:30 UTC, foram identificados o vetor de envenenamento de cache por pull_request_target em bundle-size.yml e o fork zblgg/configuration
    • As entradas de cache de todos os repositórios GitHub TanStack/* foram removidas via API
    • Um PR de hardening foi merged, reconfigurando bundle-size.yml, adicionando a guarda repository_owner e fixando por SHA as referências de actions de terceiros
    • O GitHub Security Advisory oficial foi publicado e um CVE foi solicitado

Causa raiz

  • Combinação de três vulnerabilidades

    • O ataque exigiu as três vulnerabilidades; qualquer uma delas isoladamente não seria suficiente
    • O código de PR de fork passava para o cache do repositório base, o cache do repositório base passava para o runtime do workflow de release, e o runtime do workflow de release levava à permissão de escrita no registro npm, conectando assim as fronteiras de confiança de cada vulnerabilidade
  • Padrão “Pwn Request” de pull_request_target

    • O bundle-size.yml era executado com pull_request_target para PRs de fork e, nesse contexto de trigger, fazia checkout da merge ref do PR do fork antes de executar o build
    • A estrutura principal era a seguinte
    on:
      pull_request_target:
        paths: ['packages/**', 'benchmarks/**']
    
    jobs:
      benchmark-pr:
        steps:
          - uses: actions/checkout@v6.0.2
            with:
              ref: refs/pull/${{ github.event.pull_request.number }}/merge # fork's merged code
    
          - uses: TanStack/config/.github/setup@main # transitively calls actions/cache@v5
    
          - run: pnpm nx run @benchmarks/bundle-size:build # executes fork-controlled code
    
    • O autor do workflow tentou separar os jobs comment-pr e benchmark-pr para dividir as fronteiras de confiança, e o comentário no YAML indicava a intenção de manter o benchmark-pr como “untrusted with read-only permissions”
    • Porém, o salvamento post-job de actions/cache@v5 não é bloqueado por permissions:, e a escrita no cache usa um token interno do runner, não o GITHUB_TOKEN do workflow
    • Portanto, a configuração permissions: contents: read não impedia a mutação do cache
    • O escopo do cache é por repositório, e execuções com pull_request_target usando o escopo de cache do repositório base compartilham esse escopo com pushes para main
    • Assim, um PR executado no escopo de cache do repositório base pode contaminar uma entrada de cache que o workflow de produção em main irá restaurar depois
  • Envenenamento de cache no GitHub Actions

    • O vite_setup.mjs malicioso foi projetado para gravar dados de acordo com a chave pnpm-store que o workflow legítimo release.yml calcularia e consultaria
    • A chave alvo tinha o formato Linux-pnpm-store-${hashFiles('**/pnpm-lock.yaml')}
    • Ao fim do job benchmark-pr, o post-step de actions/cache@v5 salvava o pnpm store contaminado exatamente com essa chave
    • Depois, quando o release.yml foi executado em um push para main, o step Setup Tools restaurou a entrada contaminada exatamente como planejado
    • Esse tipo de ataque pertence à família de envenenamento de cache do GitHub Actions documentada por Adnan Khan em 2024, e não é um bug restrito à TanStack, mas uma questão de design do GitHub Actions que exige mitigação consciente
  • Extração de token OIDC da memória do runner

    • O release.yml declarava legitimamente id-token: write, pois isso é necessário para o trusted publishing via OIDC no npm
    • Quando o pnpm store contaminado é restaurado no runner, um binário controlado pelo atacante passa a existir no disco e é chamado no step de build
    • Esse binário localiza o processo Runner.Worker do GitHub Actions via /proc/*/cmdline e lê /proc/<pid>/maps e /proc/<pid>/mem para despejar a memória do worker
    • Em seguida, extrai da memória o token OIDC gerado sob demanda pelo runner com a configuração id-token: write
    • Com o token extraído, autentica diretamente uma requisição POST para registry.npmjs.org, contornando completamente o step Publish Packages do workflow
    • Esse método de extração de memória é o mesmo usado no comprometimento de tj-actions/changed-files em março de 2025, e foi usado o mesmo script Python com comentário de atribuição incluído
    • O atacante não inventou uma técnica nova, apenas recombinou pesquisa pública
  • Por que cada elemento isoladamente não era suficiente

    • O pull_request_target por si só pode ser usado para tarefas confiáveis, como label ou comentário
    • Apenas o envenenamento de cache dentro de uma dependência já comprometida ainda exigiria um veículo separado para publicar
    • Apenas a extração de token OIDC exigiria execução prévia de código no runner

Detecção e IOC

  • Caminho de detecção

    • A detecção ocorreu de fora, não internamente
    • carlini abriu a issue #7383 cerca de 20 minutos após a publicação e forneceu a análise técnica completa
    • Tanner recebeu uma ligação da Socket.dev confirmando a situação logo depois de iniciar a war room
  • Fingerprints para mantenedores downstream e ferramentas de segurança

    • Nos manifests dos pacotes @tanstack/*, a seguinte entrada em optionalDependencies é o IOC principal
    "optionalDependencies": {
      "@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
    }
    
    • O IOC de arquivo é router_init.js na raiz do pacote; ele tem cerca de 2,3 MB e não está incluído em "files"
    • A chave de cache é Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11
    • As URLs do payload de segundo estágio são https://litter.catbox.moe/h8nc9u.js, https://litter.catbox.moe/7rrc6l.mjs
    • A rede de exfiltração é filev2.getsession.org, seed{1,2,3}.getsession.org
    • A identidade de commit forjada é claude <claude@users.noreply.github.com>, um email no-reply do GitHub manipulado, não o Anthropic Claude real
    • As contas reais do atacante são zblgg id 127806521, voicproducoes id 269549300
    • O fork do atacante é github.com/zblgg/configuration, uma renomeação do fork de TanStack/router para evitar detecção em buscas
    • O commit órfão com o payload na rede de forks é 79ac49eedf774dd4b0cfa308722bc463cfe5885c
    • As execuções de workflow que realizaram a publicação maliciosa foram github.com/TanStack/router/actions/runs/25613093674 tentativa 4 e github.com/TanStack/router/actions/runs/25691781302`

Lições

  • O que deu certo

    • Pesquisadores externos detectaram o incidente cerca de 20 minutos depois e o reportaram com todos os detalhes técnicos
    • A equipe de mantenedores se coordenou imediatamente em vários fusos horários
    • A comunidade de detecção obteve padrões públicos de IOC claros em poucas horas
  • O que precisava ter sido melhor

    • Não havia alertas internos, e o comprometimento foi descoberto por terceiros
    • É necessário monitoramento próprio de publicação, e há planos para cooperar mais de perto com empresas de pesquisa em segurança do ecossistema que consigam detectar esse tipo de problema rapidamente e encurtar o loop de feedback
    • O workflow pull_request_target era conhecido há muito tempo como um padrão perigoso, mas não foi auditado
    • Referências flutuantes de actions de terceiros como @v6.0.2 e @main criam um risco permanente de supply chain, independentemente deste incidente
    • Por causa da política do npm de “não permitir unpublish se houver dependentes”, o unpublish foi impossível para quase todos os pacotes afetados
    • Foi necessário depender da equipe de segurança do npm para remover os tarballs no lado do registry, o que acrescentou mais algumas horas em que os tarballs maliciosos permaneceram instaláveis
    • A lista de 7 mantenedores do scope do npm significa 7 alvos separados de roubo de credenciais para o mesmo blast radius
    • O binding de trusted publisher via OIDC não tem revisão por publicação; depois de configurado, qualquer code path dentro do workflow pode emitir um token com permissão de publicação
    • As alternativas necessárias são migrar para tokens classic de curta duração com revisão manual, ou adicionar verificação de proveniência da origem para detectar publicações feitas em etapas inesperadas do workflow
  • Onde houve sorte

    • O invasor escolheu uma payload que quebrou os testes, então a etapa normal de publicação foi ignorada e não foi gerado um tarball com aparência mais limpa
    • Por isso, o ataque apareceu de forma barulhenta o suficiente para ser detectado rapidamente
    • Se o invasor tivesse sido mais cuidadoso e não tivesse quebrado os testes, poderia ter publicado em silêncio por mais algumas horas
    • O invasor reutilizou um script público de dump de memória que incluía um comentário de atribuição e, como não escreveu código novo, a correspondência de IOC ficou mais rápida

Perguntas em aberto

  • É preciso confirmar se a etapa Setup Tools de bundle-size.yml realmente chamou actions/cache@v5
  • É preciso verificar lendo um dos logs de post-job de uma execução pull_request_target do PR #7378; um exemplo de run id é 25666610798
  • É preciso confirmar o que havia no commit head original do PR antes de ele desaparecer com um force-push; isso pode ter ficado no reflog do GitHub
  • É preciso confirmar se a forma como o commit malicioso entrou no git object store do fork foi um git push direto ou uma criação pela interface web do GitHub, que deixaria uma entrada no audit log
  • É preciso verificar se voicproducoes é uma conta real ou uma sock puppet, comparando com seu histórico de atividade
  • É preciso verificar se o cache do npm, que parece ter 6 entradas duplicadas linux-npm-store-*, também foi contaminado e se foi realmente usado
  • É preciso verificar se o ataque precisava do Nx Cloud ou se teria funcionado apenas com o cache do GitHub Actions
  • É preciso verificar se é possível identificar outros forks dentro da rede de forks de TanStack/router contendo o commit órfão da payload
  • Se outro fork estiver hospedando esse commit, a acessibilidade via github:tanstack/router#79ac49ee... permanece e a limpeza fica mais difícil
  • É necessária uma auditoria para verificar se outros repositórios da TanStack, como router, query, table, form e virtual, usam o mesmo padrão de estilo de bundle-size.yml
  • É preciso obter com o suporte do npm o número de usuários que realmente baixaram as versões afetadas durante a janela de publicação
  • É preciso verificar se as máquinas dos 7 mantenedores também foram comprometidas separadamente
  • As publicações maliciosas não usaram um token npm de mantenedor, mas as máquinas dos mantenedores podem ser um alvo secundário da lógica de autopropagação

Referências

1 comentários

 
GN⁺ 2 시간 전
Comentários no Hacker News
  • É preciso ter cuidado ao revogar tokens. Parece que o payload instala um dead-man's switch em ~/.local/bin/gh-token-monitor.sh e o registra como um serviço de usuário do systemd no Linux e como LaunchAgent com.user.gh-token-monitor no macOS
    Com o token roubado, ele faz polling em api.github.com/user a cada 60 segundos e, se o token for revogado e retornar HTTP 40x, executa rm -rf ~/
    https://github.com/TanStack/router/issues/7383#issuecomment-...

    • Na prática, se você instalou malware, de qualquer forma precisa resetar totalmente o computador
    • Assustador. É uma situação de destruição mútua assegurada
      Os próximos 5 anos no mundo do software parecem que vão ser bem brutais, e sistemas air-gapped devem ganhar muita importância
    • O certo era sempre ter backup configurado, mas se esse incidente fizer as pessoas adotarem backup, já é algum consolo
  • O pacote npm @mistralai/mistralai também foi comprometido como parte desse worm
    https://github.com/mistralai/client-ts/issues/217
    Neste momento ele foi removido do registro do npm

  • Infelizmente, isso parece ser evidência de que só Trusted Publishing não basta para publicar com segurança a partir de CI. Se houver um invasor dentro do pipeline de CI ou permissões de administrador de repositório roubadas, publicar continua sendo fácil
    Isso não é uma informação nova, e o Trusted Publishing também não foi projetado para garantir isso, mas ao migrar de publicação local com autenticação de dois fatores para Trusted Publishing você passa a abrir esse vetor de ataque via comprometimento de CI. Na prática, desaparece o segundo fator que antes bloqueava o npm publish quando o trabalho era feito localmente
    Pelo que tudo indica até agora, o atacante assumiu o controle do pipeline de CI/CD e, como não havia segundo fator no npm publish, conseguiu roubar o token OIDC e concluir a publicação. Curiosamente, embora a tarefa de deploy em si tenha falhado, o payload no commit malicioso aparentemente conseguiu se publicar usando o token OIDC do workflow
    O ideal seria manter o modelo de Trusted Publisher sem tokens de longa duração, mas com deploy por CI ainda exigindo um segundo fator fora do GitHub. Ou seja, seria preciso algum tipo de deploy em etapas, em que alguém no lado do npm promovesse o artefato para publicação real com autenticação de dois fatores
    Se publicar só depende do modelo de confiança do GitHub, qualquer pessoa que roube um token de administrador do repositório ou injete código malicioso no pipeline pode concluir a publicação sem dificuldade. Com um segundo fator real fora do contexto do GitHub, ainda seria possível vandalizar o repositório ou plantar malware, mas não publicar no registro sem esse segundo fator

    • Tenho um pacote de popularidade mediana e ainda uso publicação local com autenticação de dois fatores. Trusted Publishing parece complexo demais e dá a impressão de estar sempre sendo comprometido, então talvez seja complexo demais para operarmos com segurança e talvez precise ser redesenhado do zero
    • Ainda acho que Trusted Publishing é uma grande melhoria, mas a ideia de exigir um segundo fator ao marcar um release como realmente público é boa. Isso tornaria muito difícil executar worms desse tipo em CI
    • Eu queria assinatura com toque usando algo como uma YubiKey. A própria ideia de confiar que a nuvem vai gerenciar as credenciais por você parece um erro
    • O blog da astral mostrou recentemente como usar Trusted Publishing e ainda assim manter um gate de release, ou seja, colocando aprovação manual no workflow de release. Infelizmente, a documentação de Trusted Publishing de NPM/PyPI/Rubygems nem sequer menciona essa possibilidade, muito menos a oferece por padrão
    • Nunca entendi por que as pessoas dizem que Trusted Publishing faz tanta diferença nesse tipo de ataque à cadeia de suprimentos
  • Post-mortem: https://tanstack.com/blog/npm-supply-chain-compromise-postmo...

    • Agradeço o post-mortem da TanStack, mas me parece que a questão de segurança do ecossistema npm como um todo ainda continua sendo uma preocupação em aberto
      Fico me perguntando se existe alguma evidência de que subpacotes que possam ter importado ou incluído pacotes da TanStack possam ser considerados seguros
  • Scripts de postinstall são fatais. Todo mundo deveria usar pnpm
    Não faz sentido que commits “órfãos” enviados para um FORK possam provocar esse tipo de coisa no cliente npm. Na minha opinião, o GitHub também tem uma grande responsabilidade. É completamente insano que commits de forks maliciosos possam ser acessados por meio do armazenamento compartilhado de objetos do GitHub com URIs que não os distinguem de um repositório legítimo

    • Se você executar o app com a dependência atualizada, esse código vai rodar de qualquer forma. Ser root ou não root não é o ponto; o importante é que as coisas relevantes ficam acessíveis com as permissões do usuário que executa a aplicação
    • Não entendo como isso não é uma falha P0 do GitHub. Alguém consegue explicar?
      Quando li pela primeira vez, achei que tinham usado a palavra “fork” errado e que na verdade queriam dizer um branch do repositório oficial. Pensei que aquilo não podia ser real, mas meu Deus
  • https://tanstack.com/blog/npm-supply-chain-compromise-postmo...
    A TanStack acabou de publicar seu post-mortem sobre o incidente

  • Um lembrete para configurar o ambiente npm de forma segura
    https://gajus.com/blog/3-pnpm-settings-to-protect-yourself-f...
    Algumas configurações já podem reduzir bastante o problema

    • No npm v11 ou superior também existe allow-git=none: https://github.blog/changelog/2026-02-18-npm-bulk-trusted-pu...
    • Acho que esse texto está errado sobre a idade mínima de release do npm. 1) O nome da configuração é min-release-age. 2) Por algum motivo fizeram isso em dias, não em minutos: https://docs.npmjs.com/cli/v11/using-npm/config#min-release-...
      Na minha opinião, o espaço dos gerenciadores de dependência está totalmente fragmentado sem necessidade
    • Dizer que definir a idade mínima para 7 dias faz com que você “nunca” sofra uma vulnerabilidade de cadeia de suprimentos no npm é exagero
    • Todas as dependências devem ser fixadas obrigatoriamente
      Se a dependência de versão do pacote estiver como ^1.0.0 ou até mesmo "*", pare de ler e fixe imediatamente uma versão segura
  • Fiz isso correndo com Claude para tentar ajudar a limitar a propagação. Obviamente é preciso verificar por conta própria, mas ele varre a máquina em busca dos pacotes comprometidos mencionados: https://github.com/PaulSinghDev/tanstack-shai-hulud-fix

  • Parece que chegamos ao ponto em que todo mundo vai precisar executar cada projeto em uma VM separada
    Dadas as vulnerabilidades recentes de escalonamento de privilégio local, Docker sozinho claramente não basta. Afinal, contêineres nunca foram projetados para ser a principal fronteira de segurança

    • Devcontainers são a forma mais conhecida desse conceito de “ambiente de desenvolvimento isolado”, mas não são uma VM completa e também não protegeriam totalmente nesse caso. As credenciais do GitHub acabam entrando automaticamente no contêiner
      Se houver outros serviços de nuvem aos quais se precisa acessar de dentro do contêiner, esse ladrão de credenciais também vai pegar isso. Ainda assim, reduz o raio de impacto, então já é uma melhora
    • O QubesOS está na direção certa. Dá vontade de ter várias VMs na base e camadas e mais camadas de segurança
    • Se você realmente quiser usar contêineres, uma opção é colocar uma VM por contêiner. Tenho ficado bem tranquilo nas últimas semanas justamente por rodar tudo em VMs, e não em algum serviço Kubernetes arbitrário
    • Felizmente, projetos que usam ecossistemas de linguagens mais seguras como C e C++ estão livres desse problema :-)
  • Uau, mais um pacote enorme. Estou repostando o aviso de utilidade pública que publiquei depois de Axios e LiteLLM terem sido comprometidos. O trecho sobre scripts de ciclo de vida também se aplica aqui
    npm/bun/pnpm/uv agora todos suportam configuração de idade mínima de release para pacotes. Também coloquei ignore-scripts=true no ~/.npmrc, e pela análise isso sozinho já poderia ter mitigado a vulnerabilidade. bun e pnpm não executam scripts de ciclo de vida por padrão
    Para definir globalmente a idade mínima de release em 7 dias, faça assim
    ~/.config/uv/uv.toml
    exclude-newer = "7 days"
    ~/.npmrc
    min-release-age=7 # days
    ignore-scripts=true
    ~/Library/Preferences/pnpm/rc
    minimum-release-age=10080 # minutes
    ~/.bunfig.toml
    [install]
    minimumReleaseAge = 604800 # seconds
    Se precisar sobrescrever a configuração global, use flags de CLI
    npm install --min-release-age 0
    pnpm add --minimum-release-age 0
    uv add --exclude-newer "0 days"
    bun add --minimum-release-age 0
    Só acrescentando mais uma coisa: parece haver preocupação de que adotar tempos de espera para dependências em larga escala atrase a descoberta de vulnerabilidades ou de que esse tempo de espera seja uma forma de pegar carona no trabalho dos outros, mas eu não concordo. O que se troca pelo tempo de espera de dependência é preferência temporal, e sempre vai existir gente com preferência temporal maior que a minha
    0: https://news.ycombinator.com/item?id=47582220
    1: https://news.ycombinator.com/item?id=47513932

    • Concordo. Ainda bem que ativei essas configurações em março, antes das duas últimas ondas. Além disso, vale a pena commitar o lockfile no repositório e ter cuidado ao adicionar novas dependências
      Para evitar mudanças inesperadas, use pnpm install --frozen-lockfile. Também é preciso lembrar que, se você não definiu min-release-age, pode acabar puxando os pacotes afetados por meio de dependências transitivas. Se possível, também é bom fixar a versão do gerenciador de pacotes