1 pontos por GN⁺ 6 일 전 | 1 comentários | Compartilhar no WhatsApp
  • O pacote Bitwarden CLI para npm foi comprometido como parte do ataque de cadeia de suprimentos da Checkmarx em andamento, e o impacto confirmado até agora se limita ao build @bitwarden/cli 2026.4.0
  • O malware bw1.js incluído no pacote usa a mesma infraestrutura e o mesmo método de ofuscação, como audit.checkmarx[.]cx/v1/telemetry, e também se alinha a indícios de comprometimento de CI/CD por meio de uma GitHub Action comprometida
  • O escopo de coleta vai muito além de tokens do GitHub, alcançando credenciais da AWS, Azure e GCP, .npmrc, chaves SSH, variáveis de ambiente e até arquivos de configuração do Claude/MCP
  • As informações roubadas são usadas para criar e commitar em repositórios públicos no GitHub, espalhar o ataque por republicação com tokens npm e injeção de workflows, além de incluir mecanismos de persistência como modificação de ~/.bashrc e ~/.zshrc
  • Organizações que usam o Bitwarden CLI devem tratar este incidente como exposição de credenciais e comprometimento de CI/CD, com foco na revisão de logs de CI e na rotação de segredos potencialmente expostos

Visão geral

  • O pacote npm do Bitwarden CLI foi comprometido como parte do ataque de cadeia de suprimentos da Checkmarx em andamento, e a versão afetada confirmada é @bitwarden/cli2026.4.0
    • O código malicioso estava presente em bw1.js, incluído no pacote
    • O vetor de ataque é consistente com indícios de uso de uma GitHub Action comprometida dentro do pipeline de CI/CD da Bitwarden, seguindo o mesmo padrão de campanha observado em outros repositórios
  • Até o momento, o escopo confirmado está limitado ao build do Bitwarden CLI, e o comprometimento segue o vetor de supply chain via GitHub Actions identificado na campanha mais ampla da Checkmarx campaign
    • Apenas o pacote CLI para npm está relacionado ao incidente
    • Até agora não foi confirmado impacto na extensão do Chrome, no servidor MCP ou em outros artefatos oficiais
  • A investigação continua em andamento, e uma análise técnica completa, as versões afetadas, os indicadores de comprometimento e as orientações de resposta serão divulgados posteriormente
  • Se você usa o Bitwarden CLI, é necessário revisar os logs de CI e rotacionar os segredos que possam ter sido expostos

Análise técnica

  • O payload malicioso bw1.js compartilha a infraestrutura central com o mcpAddon.js da Checkmarx analisado no dia anterior
    • Usa o mesmo endpoint de C2, audit.checkmarx[.]cx/v1/telemetry, e está ofuscado com __decodeScrambled e a seed 0x3039
    • Também realiza exfiltração baseada em commits via API do GitHub e roubo de tokens com republicação via registro npm
  • A estrutura do payload embutido também pertence à mesma família
    • Dentro de uma estrutura gzip+base64 há um script Python que varre a memória do Runner.Worker do GitHub Actions em busca de tokens do GitHub
    • Também inclui um loader setup.mjs para pacotes npm republicados, um workflow YAML do GitHub Actions, uma chave pública RSA hardcoded e uma string de manifesto ideológico
  • O escopo de coleta de credenciais é muito amplo
    • Tokens do GitHub são coletados por scraping da memória do Runner.Worker e de variáveis de ambiente
    • Credenciais da AWS são procuradas em arquivos sob ~/.aws/ e em variáveis de ambiente
    • Tokens do Azure são coletados por meio do azd, e credenciais da GCP por gcloud config config-helper
    • .npmrc, chaves SSH, variáveis de ambiente e arquivos de configuração do Claude/MCP também estão entre os alvos
  • O método de exfiltração via GitHub também foi confirmado em detalhes
    • O malware cria repositórios públicos sob a conta da vítima seguindo a convenção de nomes com tema de Dune {word}-{word}-{3digits}
    • Em seguida, commita resultados criptografados e insere tokens na mensagem de commit junto com o marcador LongLiveTheResistanceAgainstMachines
  • O mecanismo de propagação pela cadeia de suprimentos também está presente
    • Com tokens npm roubados, ele procura pacotes com permissão de escrita e os republica com um preinstall hook injetado
    • Também injeta workflows do GitHub Actions para coletar mais segredos dos repositórios
  • Existe um kill switch para locale russo
    • Se o locale do sistema começar com "ru", o malware encerra silenciosamente
    • Ele verifica Intl.DateTimeFormat().resolvedOptions().locale e as variáveis de ambiente LC_ALL, LC_MESSAGES, LANGUAGE e LANG
  • O runtime é Bun v1.3.13, baixado do GitHub Releases

Diferenças em relação ao incidente da Checkmarx

  • O bw1.js contém indicadores adicionais de comprometimento que não apareciam na documentação do incidente da Checkmarx
    • Usa o arquivo de lock hardcoded /tmp/tmp.987654321.lock para impedir execução simultânea
    • Injeta o payload em ~/.bashrc e ~/.zshrc para garantir persistência em perfis de shell
    • Usa branding explícito, definindo a descrição do repositório como Shai-Hulud: The Third Coming e incluindo a string de debug "Would be executing butlerian jihad!"
  • Embora as ferramentas compartilhadas sugiram fortemente conexão com o mesmo ecossistema de malware, as assinaturas operacionais tornam a atribuição mais difícil
    • Após a descoberta do ataque à Checkmarx, a TeamPCP alegou autoria por meio da conta social @pcpcats
    • Esse malware tentou se disfarçar com descrições aparentemente legítimas
  • Este payload adota uma postura pública diferente
    • Marcas ideológicas como nomes de repositórios Shai-Hulud, o manifesto "Butlerian Jihad" e mensagens de commit defendendo resistência contra máquinas aparecem diretamente dentro do malware
    • Permanecem em aberto várias possibilidades: outro operador usando a mesma infraestrutura, uma facção mais ideológica ou uma mudança na postura pública da campanha

Recomendações

  • Organizações que instalaram o pacote npm malicioso do Bitwarden devem tratar este incidente como um caso de exposição de credenciais e comprometimento de CI/CD
  • Remova imediatamente o pacote afetado de sistemas de desenvolvimento e ambientes de build, e substitua todas as credenciais que possam ter sido expostas nesses ambientes
    • Isso inclui tokens do GitHub, tokens npm, credenciais de nuvem, chaves SSH e segredos de CI/CD
  • No GitHub, é preciso verificar criação não autorizada de repositórios e workflows anormais
    • Verifique arquivos inesperados em .github/workflows/, execuções suspeitas de workflow, downloads de artifacts e repositórios públicos que sigam o padrão de nome com tema de Dune {word}-{word}-{3digits}
    • Se houver possibilidade de impacto, verifique os repositórios recém-publicados em busca das palavras-chave abaixo
      • atreides
      • cogitor
      • fedaykin
      • fremen
      • futar
      • gesserit
      • ghola
      • harkonnen
      • heighliner
      • kanly
      • kralizec
      • lasgun
      • laza
      • melange
      • mentat
      • navigator
      • ornithopter
      • phibian
      • powindah
      • prana
      • prescient
      • sandworm
      • sardaukar
      • sayyadina
      • sietch
      • siridar
      • slig
      • stillsuit
      • thumper
      • tleilaxu
  • No npm, deve-se auditar se houve publicações não autorizadas
    • Verifique publishes não aprovados, mudanças de versão e hooks de instalação recém-adicionados
  • Em ambientes de nuvem, os logs de acesso devem ser reavaliados
    • É necessário rastrear acessos anormais a segredos, uso de tokens e credenciais recém-emitidas
  • Em endpoints e runners, é preciso rastrear a infraestrutura de exfiltração observada e os vestígios de acesso a arquivos
    • Procure conexões externas para audit[.]checkmarx[.]cx
    • Verifique se houve execução de Bun em ambientes onde isso não costuma ocorrer
    • Examine vestígios de acesso a .npmrc, .git-credentials, .env, armazenamentos de credenciais em nuvem, gcloud, az e azd
    • Também verifique a presença de /tmp/tmp.987654321.lock e modificações em ~/.bashrc e ~/.zshrc
  • No GitHub Actions, revise se houve criação de workflows não autorizados
    • É preciso confirmar se workflows foram criados em branches temporárias
    • Também deve ser verificado se artifacts como format-results.txt foram gerados ou baixados
  • No longo prazo, é necessário reduzir o raio de impacto de futuros incidentes de supply chain
    • Reduza o escopo de permissões dos tokens e, quando possível, use credenciais de curta duração
    • Restrinja permissões de criação e publicação de pacotes e fortaleça as permissões do GitHub Actions
    • Desative acesso desnecessário a artifacts e monitore repositórios públicos ou mudanças em workflows criados fora do processo normal de release

Indicadores de comprometimento

1 comentários

 
GN⁺ 6 일 전
Comentários do Hacker News
  • Fico me perguntando se existe uma defesa melhor do que impor um tempo mínimo de espera antes do release
    Se tivessem colocado só min-release-age=7 no .npmrc, parece que as 334 pessoas que baixaram o @bitwarden/cli 2026.4.0, publicado há cerca de 19 horas antes de ser identificado como malicioso, teriam escapado
    Isso também parece se aplicar razoavelmente bem aos casos de axios, ua-parser-js e node-ipc; não impediria algo como event-stream, que ficou dormente por muito tempo, mas ainda assim parece eficaz contra a maioria dos ataques agudos de cadeia de suprimentos
    Há exemplos de configuração de como adicionar esse tempo de espera em npm/pnpm/bun/uv, e como não havia uma ferramenta de um clique para verificar e aplicar isso, acabei criando https://depsguard.com
    Também acabei de ver https://cooldowns.dev, que segue uma ideia parecida

    • Estou usando o Aikido safe-chain
      Ele não só impõe um tempo mínimo de espera para releases, como também funciona como um wrapper em torno de npm/uv etc., verificando cada dependência antes da instalação contra um banco de dados comercial de vulnerabilidades para checar problemas conhecidos ou sinais suspeitos
    • A ideia de cooldown é boa, mas também fico pensando se esse ataque teria sido pego caso ninguém tivesse atualizado imediatamente
      Na prática sempre vai ter alguém atualizando na hora, mas parece que o próprio processo de descobrir esse tipo de incidente depende bastante desses usuários que atualizam rápido
    • Acho melhor começar por não colocar backend ou ferramentas de CLI no NPM
    • Para instalações novas até vai, mas para dependências já existentes talvez bastasse fixar em versões de patch e fixar o sha
    • Esses ataques em geral não chegam até o código-fonte upstream, então uma abordagem de build a partir do source, como https://www.chainguard.dev/libraries, bloquearia uns 98% deles
      Se for inevitável puxar binários diretamente do registro, o cooldown pode reduzir um pouco o risco
      Para os casos mais raros em que o comprometimento chega até o GitHub, parece necessário combinar heurísticas de commits e mantenedores com análise de mudanças de código baseada em IA, e revisão humana quando houver sinais estranhos
      Trabalho nisso, aliás
  • O ponto central deste incidente é que o pipeline de build foi comprometido, e foi assim que os pacotes contaminados foram publicados
    Ainda assim, se você coloca algo importante para o trabalho no npm, acho melhor fixar as dependências
    Muita gente acha que o lockfile basta, mas se ainda houver um intervalo ^, ao atualizar o lockfile você pode acabar trazendo uma nova versão que não escolheu explicitamente
    Se for um sistema capaz de afetar a sobrevivência da empresa, esse nível de incômodo vale a pena

    • Por outro lado, o ideal também seria que, quando uma vulnerabilidade de segurança fosse corrigida numa versão posterior, o sistema recebesse isso automaticamente
  • https://github.com/doy/rbw é uma alternativa em Rust ao Bitwarden CLI
    O ecossistema Rust também dá cada vez mais a impressão de estar caminhando para árvores de dependência grandes e profundas como no npm, mas ainda assim o número de autores em quem é preciso confiar é bem menor do que no caso típico em JavaScript

    • Olhando https://github.com/doy/rbw/blob/main/Cargo.toml#L16, aqui também há bastante dependência
      Pelo menos as versões estão fixadas
    • Fico curioso se há alguma desvantagem em usar o gerenciador de senhas embutido do Firefox
    • As pessoas parecem considerar Rust mais seguro, mas ignoram com facilidade demais o quanto o risco de trazer malware por meio de dependências aumentou
    • A combinação rbw + vaultwarden funciona bem como uma versão em Rust e auto-hospedável do Bitwarden
    • Por causa de coisas assim, talvez mais software acabe indo para stacks como .Net, em que muita coisa se resolve sem dependências de terceiros
      Ou talvez a tendência seja colocar mais funcionalidades na biblioteca padrão da linguagem
  • A experiência com o Bitwarden CLI foi péssima
    Executei bw list achando que veria só os nomes das senhas, mas na prática ele mostrou as senhas e até os códigos TOTP atuais
    O mais assustador foi que, ao entrar por ssh num servidor e abrir o weechat dentro de uma sessão tmux, o conteúdo inteiro do comando bw estava acessível no histórico de entrada do weechat
    Não faço ideia do porquê, e aquilo continuou lá mesmo atravessando sessões de tmux e weechat; só sumiu depois que reiniciei o servidor
    Depois disso removi o CLI bw imediatamente e não pretendo instalar de novo
    Uso ghostty como terminal, aliás

    • Isso parece mais uma reclamação sem relação com o tema principal
    • Fui experimentar o CLI e desisti quando vi que era baseado em JavaScript
    • Coisa realmente estranha
      Fico me perguntando se existe alguma extensão bwcli para o weechat; eu nem sabia que o Bitwarden tinha CLI até agora
      Eu uso keepass localmente
  • Nunca usei o CLI, mas uso o plugin do navegador
    Se isso for comprometido, é um desastre enorme, e não sei o que fazer para evitar
    Fico pensando se a resposta seria continuar usando uma versão antiga já verificada
    É estranho parar para pensar que uma parte considerável da minha vida depende de esses segredos continuarem secretos

    • Quanto mais pontos de integração, maior a superfície de ataque
      Por isso não uso extensão de navegador para gerenciador de senhas
      Depois de ver produtos com problemas de segurança na integração com navegador, passei a evitar completamente; confio relativamente mais na integração do iOS, mas ainda assim com cautela
    • Cooldown deveria existir por padrão em todo lugar
      Isso inclui gerenciadores de pacotes de desenvolvimento, gerenciadores de pacotes do sistema operacional, extensões de navegador e até atualizações automáticas de aplicativos independentes
      Empresas como a Socket precisam de tempo para detectar updates maliciosos; se todo mundo baixar tudo minutos após a publicação, esse tipo de detecção perde o sentido
    • Meus ativos digitais mais valiosos, minha conta de e-mail e conta do Bitwarden, estão protegidos por uma Yubikey que sempre levo comigo e outra chave de backup guardada em outro lugar
      Recomendo muito essa configuração
      O título me assustou um pouco, mas sinto que já faço tudo o que é razoável fazer sem cair em paranoia
    • Em vez do plugin de navegador, dá para usar o aplicativo desktop ou acessar o cofre web diretamente
    • Como se prevenir se resume basicamente a estes dois
      https://cooldowns.dev
      https://depsguard.com
      Eu mantenho o segundo; se conhecesse o primeiro antes, talvez nem tivesse criado o meu
      Os dois fazem quase a mesma coisa, e o meu acaba sendo um pouco exagerado por usar Rust
  • O mais importante aqui é que bastou um npm install
    Se o ponto de comprometimento é o preinstall, a ideia comum de inspecionar depois da instalação cai por terra na hora
    Nesse ponto o payload já teve chance de executar
    Isso fica ainda mais interessante em ambientes de agentes, CI e sandboxes efêmeros, porque mesmo com pouco tempo de exposição, se a instalação acontece repetidamente de forma automática, já é o suficiente para ser comprometido
    Outro ponto importante é que esse payload não mirava apenas segredos: ele também tinha como alvo configurações de ferramentas de IA
    Alterar perfis de shell pode se tornar um caminho para contaminar o contexto que o próximo assistente de programação vai ler
    Escrevi mais longamente sobre essa perspectiva, junto com o trabalho do AgentSH, em https://www.canyonroad.ai/blog/the-install-was-the-attack/

    • Na prática ninguém inspeciona pacotes depois da instalação, e tratar especificamente scripts de npm install como um problema especial é uma tese já refutada várias vezes
      No fim das contas você vai executar o binário real de qualquer forma
      E, se for levar ao pé da letra, também seria possível baixar e inspecionar o pacote antes da instalação; se você não entende profundamente as garantias de comportamento e o escopo do instalador, parece ainda mais estranho confiar de forma meio improvisada no processo de baixar e descompactar código malicioso
  • Um kill switch por locale russo parece ao mesmo tempo ousado e covarde

    • O pior é que nem dá para saber se isso é um rastro real ou uma false flag
    • Isso faz lembrar todo tipo de ditado como Discretion is the better part of valor
      Em resumo, parece a postura de não atirar no próprio pé
    • Isso por si só não é prova conclusiva
      No vazamento do Vault7 havia menções de que NSA e CIA deixavam rastros assim de propósito para confundir a origem, e é uma técnica que outros atores estatais certamente também poderiam usar
    • Também parece uma operação de intimidação feita por outro país
    • Quem configuraria o locale desse jeito num job de GitHub CI para publicar no npm?
      Parece um rastro de despiste óbvio demais, mas ao mesmo tempo reforça bastante a impressão de envolvimento de um ator estatal
  • A vida de quem usa KeePass tem muito menos desse tipo de estresse
    Só nos últimos 5 anos, usar KeePass em infraestrutura local me poupou de vários incidentes de segurança

    • Aqui o problema não era o vault em si, mas a ferramenta de acesso
      Não vejo por que algo assim seria impossível com uma ferramenta de acesso ao KeePass; então não entendo bem qual seria a diferença
    • Preciso acessar as senhas tanto da infraestrutura quanto do celular, então tenho curiosidade de saber como isso seria resolvido com KeePass
      Sempre achei que não dava, mas para ser sincero nunca investiguei a fundo
    • Pode ser bom para quem consegue manter a própria infraestrutura, mas é difícil aplicar essa ideia de stress free ao usuário médio
    • Entendo a abordagem de arquivo único, mas na prática tenho curiosidade sobre sincronização e resolução de conflitos
      O que acontece se dois dispositivos adicionarem senhas diferentes enquanto estão offline e depois voltarem a ficar online?
    • O que ainda não entendi no KeePass é a parte de backup em nuvem
      Se você criptografa o backup, onde guarda essa senha? E onde guarda a senha do provedor de nuvem?
  • O que mais impressiona neste ataque é que os invasores precisaram acertar exatamente o momento em que o GitHub não estava fora do ar

  • Por isso eu simplesmente não uso gerenciador de senhas de terceiros
    Porque você precisa continuar confiando que eles vão cuidar direito de segurança, updates e backups
    Criei meu próprio gerador stateless de senhas, e com isso não preciso de backup nem sincronização de dados entre dispositivos
    A ideia é usar uma senha mestra muito longa e forte, junto com o nome do serviço e o nome de usuário, e rodar um hash scrypt com parâmetros adequados para tornar brute force praticamente inviável
    Também uso 2FA nas contas importantes