Codfish/semantic-release-action GitHub Action has been compromised

varunsharma071 pts0 comments

codfish/semantic-release-action GitHub Action has been compromised - StepSecurity

Customers

Pricing

Resources

Company

Request a Demo<br>Login

Customers

Pricing

Resources

Company

Start Free

Login

Back to Blog

Threat Intel

codfish/semantic-release-action GitHub Action has been compromised

On June 24, 2026, an attacker compromised the codfish/semantic-release-action GitHub repository. At 15:39:06 UTC they force-pushed a malicious commit and repointed several version tags to that commit. As a result, any workflow running against those tags after that time executed the attacker's code inside its GitHub Actions runner.

Rohan Prabhu<br>View LinkedIn

June 24, 2026

Share on X<br>Share on X<br>Share on LinkedIn<br>Share on Facebook<br>Follow our RSS feed

Table of Contents

Loading nav...

Summary<br>On June 24, 2026 at 15:39:06 UTC, an attacker force-pushed a malicious commit to codfish/semantic-release-action and redirected several version tags to point at the malicious commit. Any workflow that ran against one of these tags after that timestamp executed the attacker's payload directly inside the GitHub Actions runner. The payload steals GitHub OIDC tokens, harvests Personal Access Tokens matching known GitHub token patterns, encrypts the collected material with AES-128-GCM, and attempts to propagate a backdoor into other repositories accessible with the stolen credentials.<br>We analyzed the malicious commit and the modified action.yml. The attacker converted the action from a Docker-based runner to a composite action, adding two steps — one to install the Bun runtime via oven-sh/setup-bun and one to execute the payload via bun run, both guarded with if: always() so the payload fires even when prior steps have failed. The malicious index.js payload is approximately 512 KB of heavily obfuscated JavaScript. The C2 exfiltration endpoint remains encoded beyond the current analysis window; this post will be updated as deobfuscation progresses.<br>Background: What Is codfish/semantic-release-action?<br>codfish/semantic-release-action is a GitHub Action that wraps semantic-release, the popular automated versioning and changelog tool. It is widely used by open-source and enterprise projects to automate release workflows — determining the next version number, generating release notes, tagging the repository, and publishing to registries, all triggered from a CI push. The action has been in active use since 2019, has over 100 GitHub stars, and is referenced by thousands of workflows that run on every push to a release branch.<br>In its legitimate form, the action is Docker-based: it builds a container from the repository's Dockerfile and runs node /action/entrypoint.js. The entrypoint is a straightforward wrapper around the semantic-release JavaScript API with no network calls beyond what semantic-release itself requires. The legitimate v5 branch and its GHCR image remain clean and unaffected by this compromise.<br>Affected Tags

Tag<br>Resolves to

v5.0.0, v5<br>5792aba

v4.0.1, v4.0.0, v4<br>5792aba

v3.5.0, v3.4.1, v3.4.0, v3.3.0, v3.2.0, v3.1.1, v3.1.0, v3.0.0, v3<br>5792aba

v2.2.1<br>5792aba

v2<br>bcb6b1d

v2.0.0<br>2845931

v1.9.0, v1<br>98a1e3e

v1.8.0<br>2fc5441

v1.7.0<br>779ea86

v1.6.2<br>e5f263f

v1.6.1<br>83036fb

The Attack: Tag Hijacking<br>Git tags are mutable references. By default, nothing prevents a repository maintainer — or anyone with push access — from repointing an existing tag to a different commit using git push --force. GitHub Actions workflows that reference an action with a mutable tag (uses: codfish/semantic-release-action@v2) resolve the tag at runtime. When the tag moves, every workflow that runs after the move silently executes the new commit's code, with no notification to the downstream workflow author.<br>At 15:39:06 UTC on June 24, 2026, the attacker introduced commit 6b9501e1889cc45c91726729610cf69c2442b8c5 and simultaneously force-updated seven version tags to point at it. The commit modifies two files relative to the last legitimate state: action.yml and index.js.<br>Modified action.yml: Docker → Composite<br>The legitimate action.yml declares a Docker runner:<br># Legitimate action.yml (v2.0.0, commit da160b1)<br>runs:<br>using: docker<br>image: Dockerfile‍<br>The malicious version replaces this with a composite action containing three steps:<br># Malicious action.yml (commit 6b9501e)<br>runs:<br>using: composite<br>steps:<br>- name: Run semantic-release<br>uses: ./<br># ... legitimate semantic-release step

- name: Setup Bun<br>uses: oven-sh/setup-bun@v2<br>if: always() # ← fires even if semantic-release step failed

- name: Run<br>shell: bash<br>if: always() # ← fires even if prior steps failed<br>run: bun run ${{ github.action_path }}/index.jsThe if: always() guard on both injected steps is deliberate: it ensures the payload runs regardless of whether the semantic-release step succeeds, fails, or is skipped. The attacker also leverages oven-sh/setup-bun — a legitimate third-party action — to install the Bun runtime, choosing Bun over Node.js specifically because Bun lacks the --require hook...

action release semantic github commit codfish

Related Articles