Aikido

Acción de GitHub comprometida codfish/semantic-release-action roba secretos de CI/CD

Escrito por
Hunter Schwartz

El 24 de junio de 2026, la codfish/semantic-release-action GitHub Action fue comprometida mediante un ataque de commit impostor. Un atacante forzó la inserción de dos commits maliciosos en el repositorio y redirigió dieciséis etiquetas hacia ellos, incluyendo las etiquetas de versión principal flotantes v2, v3, v4, y v5. Cualquier flujo de trabajo que haga referencia a la acción mediante una de esas etiquetas extraerá y ejecutará el código del atacante en su próxima ejecución de CI.

Esta acción ha sido la forma estándar de integrar semantic-release en GitHub Actions desde 2019 y cuenta con más de 100 estrellas en GitHub. Los flujos de trabajo que la utilizan para lanzamientos automatizados casi siempre tienen un GITHUB_TOKEN y con frecuencia un NPM_TOKEN con acceso de publicación, que es exactamente el tipo de acceso que un atacante desea obtener.

Cómo fueron secuestradas las etiquetas

Las etiquetas de Git no están protegidas por defecto. Cualquiera con acceso de push a un repositorio puede forzar que una etiqueta apunte a un commit diferente, y GitHub Actions resuelve una referencia de etiqueta en el momento en que se ejecuta un flujo de trabajo. Mover una etiqueta reescribe retroactivamente cada ejecución futura que la referencia, sin ninguna señal para la persona que escribió el flujo de trabajo.

El atacante utilizó esto contra codfish/semantic-release-action en dos etapas. El primer commit malicioso recogió quince etiquetas: v2.2.1, toda la línea v3 (v3, v3.0.0 hasta la v3.5.0), toda la línea v4 (v4, v4.0.0, v4.0.1), y toda la línea v5 (v5, v5.0.0). Un segundo commit es un hijo directo del primero y tomó la v2 etiqueta. Ambos commits envían una carga útil idéntica en bytes index.js payload, confirmado por hash.

Ninguno de los commits es un ancestro de la rama del repositorio principal branch. Fueron injertados como huérfanos, y luego disfrazados para evitar sospechas en un rápido git log vistazo. El primer commit reutiliza la identidad del autor, la fecha y el mensaje de commit de un commit real del 9 de noviembre 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

Esos metadatos son reales, extraídos de una fusión legítima en el historial del proyecto. Sin embargo, el contenido del archivo fue reemplazado por el payload malicioso.

¿Qué cambió en action.yml

codfish/semantic-release-action originalmente se ejecutaba como una acción basada en Docker, construyendo un contenedor desde el Dockerfile e invocando entrypoint.js. Los commits maliciosos reemplazan action.yml con una acción compuesta en su lugar:

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

El primer paso sigue llamando al real y actual codfish/semantic-release-action, anclado a un commit limpio, por lo que la acción sigue funcionando normalmente y una ejecución de workflow parece exitosa. Los dos pasos posteriores se ejecutan con if: always(), por lo que se activan independientemente de si el paso legítimo tiene éxito, falla o se omite. El segundo paso incorpora oven-sh/setup-bun, una acción de terceros real y por lo demás no relacionada, puramente para obtener el runtime de Bun en el runner de CI. El tercer paso ejecuta el payload, index.js, con bun run.

Los archivos originales del repositorio Dockerfile, entrypoint.js, y entrypoint.spec.js siguen en el árbol en este commit. Simplemente ya no se invocan, ya que una acción compuesta los ignora por completo. Dejar los archivos antiguos en su lugar es una cobertura de diff mínima. Cualquiera que revise una lista de archivos ve el contenido habitual de la acción y nada que falte de forma obvia.

La carga útil

El código inyectado index.js son 781.580 bytes de JavaScript ofuscado, estructurado como un array de cadenas con nombres de variables codificados en hexadecimal, el estilo de salida de un ofuscador de JavaScript comercial típico:

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

En el cuerpo ofuscado se encuentra la cadena thebeautifulsnadsoftime, una coincidencia casi exacta con TheBeautifulSandsOfTime y con una única letra transpuesta. Esa cadena identifica uno de los canales de entrega de información (dead drop) utilizados por el kit de herramientas de robo de credenciales Miasma, filtrado públicamente el 10 de junio de 2026. El diseño de Miasma evita un servidor C2 tradicional. En lugar de conectarse a la infraestructura del atacante, el malware busca periódicamente en la API pública de búsqueda de commits de GitHub esa cadena marcadora. Cuando encuentra un commit coincidente, trata la carga útil adjunta como un comando firmado y la ejecuta a través de eval(). Esto le da al operador una forma de entregar nueva ejecución remota de código a cada runner infectado sin tener que configurar o mantener su propia infraestructura, y sin generar el tráfico de red saliente que el monitoreo de egreso suele señalar.

Conexión con la campaña Miasma

El mismo TheBeautifulSandsOfTime marcador ya aparece en actividad de la campaña Miasma contra paquetes npm bajo el @redhat-cloud-services ámbito, y en varios otros repositorios de GitHub comprometidos vinculados a la misma filtración del kit de herramientas. Una vez que un framework de robo de credenciales como este se hace público, tiende a propagarse rápidamente, ya que cualquier operador puede ejecutarlo sin escribir sus propias herramientas. codfish/semantic-release-action encaja con ese patrón, otra instancia del mismo kit de herramientas llegando a un nuevo repositorio.

Cómo Aikido detecta esto

Si es usuario de Aikido, revise su feed central y filtre por problemas de malware. Esto aparecerá como un problema crítico de 100/100. Aikido realiza reescaneos cada noche, pero recomendamos activar un reescaneo manual ahora.

Si aún no es usuario de Aikido, puede crear una cuenta y conectar sus repositorios. Nuestra cobertura de malware está incluida en el plan gratuito, no se requiere tarjeta de crédito.

Para una cobertura más amplia en todo su equipo, Aikido's Device Protection le proporciona visibilidad y control sobre los paquetes de software instalados en los dispositivos de su equipo. Cubre extensiones de navegador, bibliotecas de código, plugins de IDE y dependencias de compilación, todo en un solo lugar. Detenga el malware antes de que se instale.

Para una protección futura, considere Aikido Safe Chain (código abierto). Safe Chain se integra en su flujo de trabajo existente, interceptando comandos npm, npx, yarn, pnpm y pnpx y verificando los paquetes con Aikido Intel antes de la instalación.

Indicadores de compromiso

Commits maliciosos

  • 5792aba0e2180b9b80b77644370a6889d5817456 (etiquetas v2.2.1, v3, v3.0.0 hasta la v3.5.0, v4, v4.0.0, v4.0.1, v5, v5.0.0)
  • bcb6b1d409144318e8fad2171d6fe06d02299d1a (etiqueta v2)

Hash de la carga útil

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

Otros indicadores

  • Cadena de marcador de dead drop: thebeautifulsnadsoftime
  • Runtime de Bun incorporado a través de oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6

Etiquetas afectadas

  • codfish/semantic-release-action@v2
  • codfish/semantic-release-action@v2.2.1
  • codfish/semantic-release-action@v3 hasta la v3.5.0
  • codfish/semantic-release-action@v4, v4.0.0, v4.0.1
  • codfish/semantic-release-action@v5, v5.0.0

Confirmado como limpio

  • codfish/semantic-release-action@v1.0.0 hasta la v1.10.0
  • codfish/semantic-release-action@v2.0.0
Compartir:

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

Escanear en busca de malware

Empieza gratis
4.7/5
¿Cansado de los falsos positivos?

Prueba Aikido como otros 100k.
Empiece ahora
Obtenga un recorrido personalizado

Con la confianza de más de 100k equipos

Reservar ahora
Escanee su aplicación en busca de IDORs y rutas de ataque reales

Con la confianza de más de 100k equipos

Empezar a escanear
Vea cómo el pentesting de IA prueba su aplicación

Con la confianza de más de 100k equipos

Empezar a probar

Asegura tu plataforma ahora

Protege tu código, la nube y el entorno de ejecución en un único sistema central.
Encuentra y corrije vulnerabilidades de forma rápida y automática.

No se requiere tarjeta de crédito | Resultados del escaneo en 32 segundos.