GitHub Action tag mutation → silent supply-chain hijack
Target pins an action by tag (uses: org/action@v3). Compromise the action repo and move the v3 tag to a malicious commit — every workflow using it pulls in the backdoor.
§ Context
Assumed environment: target uses unpinned GitHub Actions references (tags rather than 40-char commit SHAs). Attacker has gained maintainer access to a popular action repo via account takeover / abandoned dependency.
§ Steps
- 01Wait for downstream workflow runsInitial AccessT1078— Valid Accounts
- 02Push malicious commitInitial AccessT1078— Valid Accounts
- 03Exfil all secrets from runsCredential AccessCI-SECRET-IN-LOG— Secret Echo to Build Log
- 04Maintainer account takeoverInitial AccessSUP-PACKAGE-TAKEOVER— Package Maintainer Takeover
- 05Move v3 tag to malicious commitPersistenceSUP-ACTION-TAG-MUTATION— GitHub Action Tag Mutation
§ References
- T1078Valid Accounts
§ Frequently asked
- What is the "GitHub Action tag mutation → silent supply-chain hijack" attack path?
- Target pins an action by tag (uses: org/action@v3). Compromise the action repo and move the v3 tag to a malicious commit — every workflow using it pulls in the backdoor. It chains 5 steps drawn from real-world offensive-security techniques.
- What starting position does this attack require?
- The first step is Wait for downstream workflow runs (T1078) — a initial access primitive. Assumed environment: target uses unpinned GitHub Actions references (tags rather than 40-char commit SHAs).
- What is the final impact of this kill-chain?
- The final step lands on Move v3 tag to malicious commit (SUP-ACTION-TAG-MUTATION), which falls under Persistence. From here, an operator typically pivots into post-exploitation or maintains persistence.
- How can defenders detect or prevent this attack?
- Detection and prevention vary per step. Refer to each linked MITRE ATT&CK entry under "References" — every technique on that page lists defensive controls, detection telemetry, and known threat-actor usage.
§ Related dossiers
- Shared techniques2
Build-system implant → signed supply-chain backdoor (SolarWinds-class)
Compromise the target vendor's build server. A small implant rewrites a single source file at compile time — every official signed release downstream now ships the backdoor.
- Shared techniques2
Compromised extension auto-update → fleet compromise
Take over a popular extension's developer account (credential stuffing on the store, abandoned email domain). Push a malicious version — every existing install runs attacker code on next launch.
- Shared techniques2
pull_request_target injection → secrets → cloud takeover
A GitHub Actions workflow runs on pull_request_target and checks out the PR's head SHA. The attacker's PR injects code that runs with the base repo's secrets, including a cloud deploy role.
- Shared techniques2
Self-hosted runner takeover → persistent CI compromise
A public repo with self-hosted GitHub runners accepts external PRs. First malicious PR runs on the runner; the workflow drops a runner-hook that fires before every future job.
- Shared techniques2
Secret echoed to public build log → cloud takeover
A workflow accidentally runs `env` or `set -x` during debugging — the AWS access key is now in public CI logs and indexed by Google Cache / GitHub search.