Incidente · comprometimento de GitHub Action

O comprometimento do tj-actions/changed-files: o que aconteceu e por que o papel do Kilobat é pequeno

Em 14 e 15 de março de 2025, uma GitHub Action usada em mais de 23.000 repositórios despejou os segredos de cada fluxo que a executou no próprio registro desse fluxo. Tudo aconteceu em runners de CI, não nos Macs dos desenvolvedores; por isso, esta página trata principalmente do que verificar nos seus repositórios e explica claramente o pouco que o Kilobat poderia ter visto.

Quando: 14–15 de março de 2025Fontes verificadas: 1º de novembro de 2026

Em resumo

  • Protection: Não ajudaria

    O ataque ocorreu nos runners do GitHub. Seu único download veio de gist.githubusercontent.com, e nada foi enviado a um servidor externo.

  • Agent guard: Não ajudaria

    Nenhum agente esteve envolvido, e os segredos saíram pela saída do registro, não por uma conexão.

  • Registro de rede de agentes: Não ajudaria

    Fluxos executados com act rodam no Docker, cujo tráfego o Kilobat não consegue atribuir a um agente.

  • Tráfego de apps: Limitado

    Somente em um Mac que executa fluxos de trabalho por conta própria, como um runner auto-hospedado: a lista de apps mostraria as conexões do runner, incluindo o download do gist. Nada seria bloqueado.

O que aconteceu

O comunicado do GitHub sobre CVE-2025-30066 informa que o invasor alterou a maioria das tags de versão existentes da action, a partir de v1.0.0, para apontar para um commit malicioso, 0e58ed8. Todo workflow que usava a action por tag recebeu esse código na próxima execução. Ele baixou um script Python de um gist do GitHub e o executou com sudo; o script encontrou o processo Runner.Worker do GitHub, leu sua memória, selecionou os valores marcados como segredos e os imprimiu no log, codificados duas vezes em base64. Workflows fixados a um hash completo de commit não foram afetados.

Em um repositório público, os registros de workflows são públicos, portanto os segredos podiam ser lidos por qualquer pessoa. A Wiz encontrou dezenas de repositórios com segredos expostos; o risco para repositórios privados era muito menor. A StepSecurity identificou o problema porque o monitoramento do runner sinalizou uma chamada inesperada para gist.githubusercontent.com.

Os mantenedores do tj-actions disseram que um token de acesso pessoal da conta do bot havia sido comprometido. A Unit 42 rastreou a cadeia até um ponto anterior: um fluxo enviado ao repositório SpotBugs vazou o token de um mantenedor, que tinha acesso de escrita a reviewdog/action-setup; essa ação foi comprometida em seguida (CVE-2025-30154), e um fluxo do tj-actions que a usava vazou o token do bot. A Unit 42 descobriu que o primeiro alvo foi um projeto de código aberto da Coinbase, no qual o invasor não conseguiu usar os segredos.

Linha do tempo

  1. Novembro de 2024

    A Unit 42 situa os primeiros passos do invasor neste mês.

  2. 11 mar. 2025

    Um workflow enviado ao SpotBugs vaza um token de mantenedor; reviewdog/action-setup@v1 fica comprometido entre 18:42 e 20:31 UTC (Unit 42, CISA).

  3. 14 de março, por volta das 16:00 UTC

    As tags da ação apontam para o commit malicioso; a StepSecurity o detecta e confirma que a maioria das versões está afetada dentro de uma hora.

  4. 15 de março de 2025

    O gist é excluído; o GitHub retira a action do ar e a restaura após limpá-la (14:00 e 22:00 UTC, segundo a linha do tempo da StepSecurity). A versão 46.0.1 contém a correção.

  5. 18 de março de 2025

    A StepSecurity encontra várias ações reviewdog também comprometidas; a CISA publica seu alerta.

  6. 26 de março de 2025

    O alerta da CISA registra ambos os CVEs em seu catálogo de vulnerabilidades conhecidas exploradas.

  7. 2 de abril de 2025

    A Unit 42 publica as etapas de SpotBugs e Coinbase que levaram ao comprometimento.

Como apareceu na rede

Tudo aconteceu em runners de CI. A etapa maliciosa fez uma solicitação de saída, para gist.githubusercontent.com, por memdump.py; o restante ocorreu localmente no runner. Os segredos nunca foram para um servidor do invasor: foram escritos no registro, e o GitHub disponibilizou esse registro a quem o consultasse.

O script publicado encontra o processo do runner pelo sistema de arquivos /proc do Linux, e as fontes descrevem seu efeito em runners Linux. Os tokens roubados podiam então ser usados de qualquer lugar contra o GitHub e os outros serviços aos quais pertenciam.

Indicadores

Conforme documentados pelas fontes. Os domínios aparecem como texto, nunca como links, e são neutralizados ([.]) quando a fonte os neutraliza. A maior parte dessa infraestrutura já deixou de existir: os indicadores ajudam a verificar registros, arquivos e contas antigos, não a bloquear campanhas atuais.

IndicadorTipoOnde apareceObservação
0e58ed8671d6b60d0890c21b07f8835ace038e67Committj-actions/changed-filesO commit para o qual as tags reescritas apontavam.
gist.githubusercontent.com/nikitastupin/30e525b776c409e03c2d6f328f254965/raw/memdump.pyURLExecutor de CIO script que descarrega a memória. Excluído em 15 de março de 2025.
A double-base64 string in the changed-files step’s logSaída do registroRegistros de workflowPresente se o payload foi executado. Ao ser decodificado, contém os segredos da execução.
reviewdog/action-setup@v1, 11 March 2025, 18:42–20:31 UTCAção, intervalo de tempoFluxos de trabalhoCVE-2025-30154; também afetou outras actions do reviewdog que o usam.
tj-actions/changed-files, 12 March 00:00 to 15 March 12:00 UTCAção, intervalo de tempoFluxos de trabalhoO intervalo que a CISA pede para você auditar.

O que o Kilobat teria mostrado ou bloqueado

  • Tráfego de apps. Se seu Mac for um runner próprio e tiver executado a action, a lista de apps do Kilobat teria mostrado os processos do runner conectando-se a gist.githubusercontent.com. Esse host não está em nenhuma lista de ameaças nem deveria estar: gists são usados legitimamente o tempo todo.
  • Registro de rede dos agentes. Executar um workflow no Mac com act, mesmo por um agente de IA, coloca as etapas em contêineres Docker. Suas conexões saem pelo próprio processo do Docker, que o Kilobat não consegue atribuir ao agente; por isso, o registro de rede dos agentes não as listaria.
  • Protection. O Protection não tinha sobre o que agir. Se um token de um registro vazado foi usado contra você posteriormente, esse uso ocorreu nas máquinas do atacante, contra o GitHub.

Onde o Kilobat não teria ajudado

  • O comprometimento, o despejo e o vazamento dos segredos ocorreram no GitHub Actions. Uma ferramenta no seu Mac não pode ver o runner de outra pessoa.
  • Os segredos saíram pela saída de registro que o GitHub forneceu normalmente, não por uma conexão que alguém pudesse bloquear.
  • O script foi obtido de um gist hospedado no GitHub, um host que qualquer filtro de rede precisa permitir.
  • Contêineres Docker e máquinas virtuais em um Mac são opacos à visualização por processo do Kilobat.

Verifique seu Mac agora

  1. Liste os workflows de um repositório que usam as actions afetadas.

    grep -rnE "tj-actions/changed-files|tj-actions/eslint-changed-files|reviewdog/action-" .github/workflows
  2. Ou pesquise todos os seus repositórios no GitHub de uma vez.

    gh search code "tj-actions/changed-files" --owner YOUR-ACCOUNT-OR-ORG
  3. Para execuções entre 12 e 15 de março de 2025, abra o registro da etapa de arquivos alterados e procure uma sequência longa que seja decodificada duas vezes. Se encontrar uma, todos os segredos que esse fluxo podia ler estão expostos.

    echo 'PASTE-THE-STRING' | base64 -d | base64 -d
  4. Troque esses segredos, baixe os registros afetados para seu arquivo e exclua as execuções, para que os segredos deixem de ser legíveis.

  5. Encontre actions fixadas por tag em vez de commit. Fixe-as em um hash de commit completo, como recomenda o GitHub.

    grep -rnE "uses: *[^ ]+@(v[0-9][^ ]*|main|master) *$" .github/workflows
  6. Se um token usado no seu Mac foi armazenado como segredo de repositório, revogue-o em Settings › Developer settings › Personal access tokens e verifique em qual conta a CLI do GitHub está conectada.

    gh auth status

Fontes

Verificado em 1º de novembro de 2026.

Veja a que seus agentes e apps se conectam

O Kilobat é um app para a barra de menus do Mac que identifica o app, processo e agente por trás de cada conexão, mantém essas conexões longe de hosts reconhecidamente maliciosos e registra o que cada sessão de agente acessou.

Baixar para Mac ↓
brew install seifip/kilobat/kilobat