codfish semantic-release-action tag compromise
Summary
StepSecurity reported that on June 24, 2026 an attacker compromised the codfish/semantic-release-action GitHub repository and force-pushed a malicious commit, 6b9501e1889cc45c91726729610cf69c2442b8c5 (6b9501e). StepSecurity says seven existing version tags — v1.6.1, v1.6.2, v1.7.0, v1.8.0, v1.9.0, v2.0.0, and v2.2.1 — were repointed to that commit at 2026-06-24 15:39:06 UTC, so downstream workflows using those mutable tags executed attacker-controlled code on their next run.
The payload converted the action from a Docker action to a composite action that installed Bun with oven-sh/setup-bun@v2 and ran a heavily obfuscated JavaScript payload with if: always(). StepSecurity's initial analysis says the payload targeted GitHub Actions OIDC tokens and GitHub personal access tokens, encrypted collected material with AES-128-GCM, and attempted to propagate a backdoor into repositories reachable with stolen credentials.
As of a live GitHub API check during this wiki update, refs/tags/v2.2.1 resolved to 5792aba0e2180b9b80b77644370a6889d5817456, so treat the highest-risk exposure as workflow runs that resolved one of the affected tags during the malicious tag window rather than current tag state alone.
Tags
- ops
- operations
- supply-chain
- GitHub Actions
- CI/CD
- tag tampering
- mutable tags
- credential-theft
- OIDC
- GitHub tokens
- Bun
- semantic-release
Why this matters
- Release automation actions often run with package-registry, GitHub, and cloud publish credentials; compromising the release action can turn routine release jobs into secret-theft and propagation events.
- The incident repeats the core mutable-tag lesson from prior GitHub Actions compromises:
uses: owner/action@v2is only as stable as the repository's tag-protection and maintainer-account controls. if: always()on injected steps means the malicious payload still runs when the legitimate release step fails, reducing the chance that broken release behavior prevents compromise.- Bun installation is a useful CI hunt pivot: StepSecurity notes the attacker selected Bun partly because many Node.js security controls rely on
--require-style interception that does not apply to Bun. - Current clean tag resolution does not clear historical exposure. Review workflow runs in the malicious window, not just present-day repository refs.
Reported chain
- The attacker gained the ability to write to
codfish/semantic-release-actionand force-update release tags. - At
2026-06-24 15:39:06 UTC, StepSecurity says the attacker introduced commit6b9501e1889cc45c91726729610cf69c2442b8c5and repointedv1.6.1,v1.6.2,v1.7.0,v1.8.0,v1.9.0,v2.0.0, andv2.2.1to it. - The malicious
action.ymlchanged the runner type from Docker to composite. - The composite action preserved a semantic-release-looking step, then added
oven-sh/setup-bun@v2andbun run ${{ github.action_path }}/index.js, both guarded withif: always(). - The injected
index.jswas roughly 512 KB of single-line obfuscated JavaScript. - StepSecurity's static analysis identified patterns for GitHub OIDC token theft, GitHub PAT harvesting using known token formats, AES-128-GCM encryption of collected material, and repository backdoor propagation attempts.
- StepSecurity reported that the exfiltration endpoint remained encoded at publication time and said it would update the post after deeper deobfuscation.
Exposure triage
Search GitHub Actions workflow history, not only current workflow files:
uses: codfish/semantic-release-action@v1.6.1uses: codfish/semantic-release-action@v1.6.2uses: codfish/semantic-release-action@v1.7.0uses: codfish/semantic-release-action@v1.8.0uses: codfish/semantic-release-action@v1.9.0uses: codfish/semantic-release-action@v2.0.0uses: codfish/semantic-release-action@v2.2.1
Treat runs as exposed if they executed after 2026-06-24 15:39:06 UTC and before the tag was restored or replaced with a reviewed pinned SHA. Also review reusable workflows, composite actions, release templates, and organization-wide workflow generators that may reference the action indirectly.
Hunt pivots
- Unexpected
oven-sh/setup-bun@v2execution in release workflows that previously used onlycodfish/semantic-release-action. bun runexecution from a GitHub action path, especiallybun run ${{ github.action_path }}/index.js.- A sudden Docker-to-composite diff in
codfish/semantic-release-action/action.yml. - Commit
6b9501e1889cc45c91726729610cf69c2442b8c5/ short SHA6b9501eresolving under older release tags. - Large obfuscated single-line JavaScript near
index.jsin the action checkout. - GitHub OIDC token minting,
ACTIONS_ID_TOKEN_REQUEST_URL/ACTIONS_ID_TOKEN_REQUEST_TOKENaccess, or unusual calls to cloud federation endpoints from release jobs. - GitHub PAT-shaped strings found in runner memory, environment snapshots, action debug output, or exfiltration telemetry.
- New branches, workflow files, release changes, or commits made by automation identities shortly after an affected run.
Defender heuristics
- Disable or pin affected release workflows before rotating credentials; otherwise a rerun can re-steal fresh secrets.
- Rotate GitHub, npm, container-registry, cloud, package-signing, and release-automation credentials that were reachable from affected runners.
- Review GitHub audit logs for workflow runs, OIDC token requests, repository writes, tag updates, branch creations, package publishes, and secret access after the affected workflow ran.
- Prefer full-length commit SHA pinning for third-party GitHub Actions, paired with automation that periodically reviews and advances pins.
- Enable tag protection / rulesets for maintained actions and monitor release tags for forced updates, orphan commits, or commits outside expected branch ancestry.
- Treat action code as executable supply-chain input: diff the resolved action commit during incident response, not only the consuming repository's workflow YAML.
- Consider egress restrictions and runtime telemetry for release runners; release jobs often need broad credentials but rarely need arbitrary outbound destinations.
Attribution notes
StepSecurity's public post does not attribute the codfish/semantic-release-action compromise to a named actor. Keep it separate from Mini Shai-Hulud / TeamPCP unless a later public source establishes overlap. The technique overlaps with earlier GitHub Actions tag-retargeting incidents, but overlap is not attribution.
Related pages
- actions-cool GitHub Actions tag compromise
- Megalodon GitHub Actions workflow backdooring
- GitHub Actions deployment poisoning
- GitHub Actions OIDC subject-claim collisions
- Supply-chain group profile
Sources
- StepSecurity: https://www.stepsecurity.io/blog/supply-chain-compromise-codfish-semantic-release-action
- GitHub repository: https://github.com/codfish/semantic-release-action