
codfish/semantic-release-action GitHub Action has been compromised
Step Security's incident analysis of the compromise of codfish/semantic-release-action, a widely used GitHub Action wrapping semantic-release. An attacker force-pushed a malicious commit and repointed seven version tags to it, converting the action from a Docker runner to a composite action that installs Bun and runs an obfuscated 512KB payload via if: always() steps. The payload steals GitHub OIDC tokens and PATs, uses a novel GitHub commit-message dead-drop for C2, has a Russian-locale killswitch, and locked tags immutable via GitHub Rulesets to block remediation.
What it is
Step Security's forensic analysis of the June 24, 2026 supply-chain compromise of codfish/semantic-release-action. At 15:39:06 UTC the attacker force-pushed commit 6b9501e1889cc45c91726729610cf69c2442b8c5 and repointed seven version tags (including the rolling v5) to it. The action was flipped from a Docker runner to a composite action that installs Bun and runs a ~512 KB obfuscated index.js payload.
How it works
The malicious action.yml keeps the legitimate semantic-release step, then appends two steps both guarded with if: always() so the payload fires even if the release step fails or is skipped:
- name: Setup Bun
uses: oven-sh/setup-bun@v2
if: always()
- name: Run
shell: bash
if: always()
run: bun run ${{ github.action_path }}/index.jsBun was chosen deliberately because it lacks the --require hook interception most Node.js security tooling relies on. The payload runs two guards first: a Russian-locale killswitch (checks Intl.DateTimeFormat().resolvedOptions().locale and LANG/LC_ALL/LANGUAGE; halts if locale starts with ru). It then steals OIDC tokens and PATs and encrypts the loot with AES-128-GCM.
The C2 is a GitHub commit-message dead drop: the payload searches the commit API for messages matching RevokeAndItGoesKaboom:<BASE64>, where the base64 is an operator Fine-Grained PAT encrypted with AES-256-CBC under a hardcoded key. It validates candidate tokens and picks the one with the most rate limit remaining — making C2 traffic indistinguishable from normal GitHub API use and immune to domain blocking.
Preconditions / Affected
Any workflow referencing an affected mutable tag (e.g. uses: codfish/semantic-release-action@v2) that ran after 15:39:06 UTC on June 24, 2026. Tag references resolve at runtime, so the hijack executes silently with no notification to the workflow author.
What to do
- Audit CI logs for runs of this action after the compromise timestamp; treat any OIDC tokens and PATs exposed to those runners as compromised and rotate them.
- The page names one clean path: the legitimate
v5branch and its GHCR image remain unaffected. Pin to a verified commit SHA rather than a tag. - If you maintain the repo: the attacker used GitHub Repository Rulesets to make the hijacked tags immutable, so you cannot force-push clean commits until you locate and disable the attacker-created rulesets first.
Caveats
Analysis was in progress at publication. Full deobfuscation was incomplete and the C2 exfiltration endpoint remained encoded beyond the analysis window. Capabilities described are drawn from static analysis of identifiable patterns and partially decoded strings, not a complete decode; the post was to be updated as work continued.
Organisations named here
- RevokeAndItGoesKaboom
Technologies named here
- GitHub Actions
- Bun
- Node.js
- git
- codfish/semantic-release-action
- oven-sh/setup-bun
- GitHub repository rulesets
- semantic-release
Related in Supply Chain


