← voltar
CVE-2025-30066highsob ataqueCWE-506

CVE-2025-30066

93Vexday Risk Score

Priorize a correção. Ela está sob exploração confirmada pelo CISA e tem prova de conceito pública.

ssvc Actcvss 8.6epss 72%
da publicação à arma3 dias
Publicada no NVD15 de mar.
1ª PoC+3d
CISA KEV+3d
probabilidade de exploração
72%top 1% das CVEs
exploração observada
simCISA + VulnCheck
2 exploit(s) público(s)
Ação exigida pela CISAprazo federal: 2025-04-08

Apply mitigations as set forth in the CISA instructions linked below. Apply mitigations per vendor instructions, follow applicable BOD 22-01 guidance for cloud services, or discontinue use of the product if mitigations are unavailable.

Resumo

Não é uma falha de código na Action tj-actions/changed-files, e sim um comprometimento de cadeia de suprimentos: em 14-15 de março de 2025 um ator mal-intencionado reescreveu as tags git v1 até v45.0.7 do repositório para apontarem para um commit malicioso (0e58ed8), injetando código que expunha segredos do runner nos logs públicos de execução do workflow. Qualquer pipeline de CI/CD que referenciasse a Action por tag (não por SHA fixo) e executasse durante essa janela ficou exposto, sem qualquer ação do atacante contra a vítima além de ter comprometido o upstream. O impacto real depende de quais segredos estavam injetados no ambiente do runner durante a execução — em repositórios públicos, os logs (e portanto os segredos vazados) ficam visíveis para qualquer pessoa.

Detalhamento técnico

tj-actions/changed-files é uma GitHub Action de terceiros amplamente usada para detectar quais arquivos mudaram em um push ou pull request, permitindo workflows condicionais (ex.: só rodar testes em serviços alterados). Como a maioria das Actions do Marketplace, ela é referenciada por tag semver (v45, v44, v35 etc.), e tags no Git são mutáveis — podem ser reapontadas para outro commit sem gerar um novo release visível.

O atacante obteve capacidade de escrever no repositório tj-actions/changed-files e reescreveu as referências de v1 a v45.0.7 para o commit 0e58ed8, que continha código malicioso descrito pelo próprio texto da CVE como alterações na função 'updateFeatures'. Repositórios que consumiam qualquer uma dessas tags — a prática recomendada e mais comum no ecossistema — passaram a executar esse código a cada run do workflow durante a janela de 14 a 15 de março de 2025, sem qualquer mudança no arquivo de workflow da vítima.

Observações da comunidade (relatadas em issues abertas por pesquisadores como eslerm em múltiplos repositórios afetados, incluindo espressif/arduino-esp32 e modal-labs/modal-examples) descrevem o comportamento como leitura de segredos presentes na memória do processo do runner e sua impressão nos logs do step, tipicamente em texto codificado (relatos externos citam base64) para escapar da redação automática de secrets do GitHub Actions, que depende de correspondência exata de string. Isso é consistente com uma falha de exposição de informação sensível em log (CWE-200) originada por código malicioso embutido via ataque de supply chain (CWE-506 / CWE-829), e não com uma vulnerabilidade de lógica no código legítimo da Action.

O atacante não controla nada no ambiente da vítima diretamente: ele controla o conteúdo do commit para o qual as tags apontavam. O que a vítima 'controla' — e o que determina o dano — é quais secrets do GitHub Actions (tokens de nuvem, credenciais de deploy, tokens npm/PyPI, chaves de API) estavam disponíveis como variáveis de ambiente no job durante a execução comprometida.

Como é explorada

O vetor não exige nenhuma ação do atacante contra o alvo: basta que o workflow do repositório vítima invoque tj-actions/changed-files por tag (o padrão de uso documentado e mais comum) e que esse workflow tenha disparado — por push, pull_request ou qualquer outro trigger — durante a janela em que as tags apontavam para o commit malicioso, 14-15 de março de 2025. Não há necessidade de autenticação, interação do usuário ou configuração não padrão; pelo contrário, seguir a prática 'normal' de pinning por tag (em vez de SHA) era a pré-condição que tornava o ambiente vulnerável.

Uma vez executado, o código malicioso extraía segredos presentes no ambiente/memória do runner e os despejava no log da execução do step, ofuscados para evitar a redação automática de secrets do GitHub Actions. Em repositórios públicos, logs de Actions são acessíveis por qualquer visitante, o que transformou o incidente em uma exposição massiva e passiva: não é necessário 'explorar' nada além de ler o log publicado. Em repositórios privados, o vazamento fica restrito a quem já tinha acesso de leitura ao Actions do repositório, reduzindo o alcance mas não eliminando o risco caso esse acesso não seja estritamente controlado.

A CVE está no catálogo KEV da CISA e há PoC pública, refletindo que a exploração foi ativa e generalizada — o mecanismo já é conhecido em detalhe pela comunidade (GitGuardian, StepSecurity, Semgrep publicaram análises) e milhares de repositórios, incluindo projetos de peso como espressif/arduino-esp32 e modal-labs/modal-examples, foram identificados usando a versão comprometida durante a janela. O resultado final para o atacante é a obtenção de qualquer secret injetado no job — de tokens de curta duração a credenciais de nuvem com escopo amplo, dependendo de como cada pipeline estava configurado.

Versões

Afetadas
tj-actions/changed-files, tags v1 até v45.0.7, nos casos em que essas tags foram reescritas para apontar ao commit malicioso 0e58ed8 durante 14-15 de março de 2025 (qualquer workflow que referenciasse a Action por tag/versão nesse intervalo estava exposto, independentemente de qual tag específica usava).
Corrigidas em
v46 e posteriores, publicadas após a remoção das tags comprometidas e a mudança de prática do projeto para não mais reapontar tags/digests retroativamente.

Como se proteger

A correção do fornecedor é migrar para tj-actions/changed-files v46 ou posterior, versão publicada após a limpeza do incidente e após a remoção da prática de apontar tags para digests mutáveis (ver o próprio changelog e discussões do projeto, que abandonaram atualizações de tag por digest exatamente por essa exposição). Se a atualização de versão não for imediata, o paliativo real e recomendado pelo guia oficial de hardening do GitHub Actions é fixar a Action pelo SHA completo do commit (pinning por SHA), em vez de por tag — isso neutraliza qualquer reescrita futura de tag, comprometida ou não, ao custo de precisar atualizar manualmente o SHA a cada bump de versão desejado.

Quem usou qualquer tag de tj-actions/changed-files entre v1 e v45.0.7 durante 14-15 de março de 2025 deve tratar como comprometido todo secret que estivesse disponível no ambiente dos runners que executaram workflows nessa janela, e rotacionar essas credenciais — tokens de nuvem, chaves de deploy, tokens de registro de pacotes, GITHUB_TOKEN se de escopo elevado. Não basta atualizar a Action depois; o vazamento, se ocorreu, já está nos logs históricos, que também devem ser revisados e, se necessário, ter a visibilidade restringida ou removidos (em repositórios públicos, os logs ficam expostos até serem apagados ou expirarem).

Não funciona como mitigação apenas confiar na redação automática de secrets do GitHub Actions: o próprio incidente demonstra que ela é contornável por ofuscação/encoding, e a documentação oficial do GitHub já alertava que essa redação não é garantida. Também não é suficiente 'confiar' no número de versão exibido no marketplace, já que o ataque atuou sobre a própria referência de tag, não sobre o código publicado como release — motivo pelo qual pinning por SHA, e não por tag ou versão semver, é a mitigação estrutural contra esse tipo de ataque em qualquer Action de terceiro.

Como detectar

Verificar os arquivos de workflow (.github/workflows/*.yml) por uso de tj-actions/changed-files referenciado por tag ou versão semver (ex.: @v35, @v44, @v45) em vez de SHA fixo, e cruzar com o histórico de execuções (Actions runs) entre 14 e 15 de março de 2025 — qualquer run nesse intervalo usando a Action por tag deve ser considerado potencialmente comprometido. Nos logs dessas execuções específicas, procurar por blocos de texto anormalmente longos e codificados (relatos de pesquisadores mencionam conteúdo em base64) no step da Action, fora do padrão normal de output de 'changed files'.

Não há um único indicador de rede ou assinatura de payload confiável a se procurar, já que o mecanismo de exfiltração era via log do próprio CI, não tráfego de rede externo diretamente observável pela vítima; a fonte de verdade é o log histórico do workflow run e o hash do commit 0e58ed8, documentado pelos pesquisadores que analisaram o incidente. Se o repositório já sobrescreveu ou expirou os logs desse período, não há forma retroativa confiável de confirmar exploração — a rotação preventiva de secrets é a resposta indicada nesse cenário.

Pesquisado e redigido com IA a partir do advisory do fornecedor e de análises públicas, com as fontes acima. Confira sempre a versão corrigida no advisory oficial antes de agir.
tj-actions changed-files before 46 allows remote attackers to discover secrets by reading actions logs. (The tags v1 through v45.0.7 were affected on 2025-03-14 and 2025-03-15 because they were modified by a threat actor to point at commit 0e58ed8, which contained malicious updateFeatures code.)
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:N/A:N
⚠ Recursos públicos, para você avaliar a exposição de sistemas que controla ou está autorizado a testar. Teste apenas com autorização.