Tj-actions/changed-files GitHub Action Compromised – used by over 23K repos
Incident and attack behavior
- A popular GitHub Action (
tj-actions/changed-files) was compromised: manyv35+tags were retargeted to a malicious commit. - The malicious code downloaded a Python script that attempted to dump CI/CD secrets from the runner process memory and print them to stdout, relying on build logs (especially public ones) as the exfiltration channel.
- The external gist hosting the payload was later deleted, which stopped further exfiltration but did not retroactively protect any already-run workflows.
- The repo and org briefly 404’d, then reappeared. The maintainer attributes the incident to a compromised personal access token of a bot account; some commenters doubt or want more detail.
Tags, pinning, and automation bots
- A core issue: Git tags are mutable pointers, not immutable versions. The attacker simply repointed all version tags to the malicious commit, instantly “upgrading” users without config changes.
- Many argue that only commit hashes are safe for
uses:in workflows; tags (includingv4,v35.9.3, etc.) should not be trusted. - Others note that even hash pinning can be undermined by automated dependency bots (Renovate, Dependabot) that auto-update hashes and may auto-merge; this is how some projects pulled in the compromised version.
- There’s support for:
- GitHub-level “immutable tags” or tag-protection policies.
- A lockfile mechanism for actions, or tooling to auto-“bake” tags into hashes.
- New “immutable actions” features GitHub is previewing.
Trust in dependencies and the broader supply chain
- Many commenters express growing reluctance to use:
- Third-party GitHub Actions beyond official ones.
- Deep dependency trees (npm, NuGet, VS Code extensions, browser extensions).
- Strategies mentioned:
- Forking or vendoring actions and extensions; turning off auto-updates.
- Preferring “batteries-included” languages/standard libraries and minimal deps.
- Copying small snippets instead of pulling whole libraries (“a little copying is better than a little dependency”).
- Others note this is not new; it’s a classic software supply-chain issue exacerbated by cultural norms in some ecosystems (e.g., massive npm graphs) and economic pressures on maintainers.
Sandboxing, capabilities, and CI/CD design
- Strong sentiment that tools and actions should run with sharply limited capabilities:
- Default-deny network access for most tools/actions.
- Fine-grained file I/O and network policies (containers, systemd, firejail, bubblewrap, OS capabilities like pledge/Capsicum/Landlock).
- Several argue CI and CD should be separated:
- CI runners should never hold production-deployment tokens.
- CI should at most write artifacts; a separate, more tightly controlled system should handle deployment.
- Some already run all dev and builds inside VMs/containers for extra isolation.
Mitigations, tools, and vendor behavior
- StepSecurity’s hardened runner detected the incident via anomalous outbound network traffic and is promoted as a defense; some appreciate the detection, others criticize the surrounding marketing and paywalled features.
- Other vendors push static/ML-based malicious-code detectors; several commenters are skeptical, arguing attackers will adapt and obfuscate once they know the rules.
- Suggestions include:
- Org-level whitelists for allowed actions, ideally pinned by hash.
- Disabling or tightly constraining third-party actions for paid orgs.
- Better defaults and documentation from GitHub (e.g., examples using hashes, not tags).
Impact, response, and unresolved questions
- The action was widely used (tens of thousands of repos), so many organizations are now:
- Removing the action.
- Rotating secrets, especially where logs are public or broadly accessible.
- Community members published drop-in forks and mirrors that remove the malicious code.
- Some worry about stolen tokens from prominent public projects and downstream compromise of package registries; the real scope remains unclear.
- A recurring pessimistic theme: the fundamental tension between staying up-to-date (for security fixes) and avoiding malicious updates is unsolved; automation helps with speed but can amplify attacks.