Apiiro Blog ﹥ Practical prevention of the next supply…
Educational, Research

Practical prevention of the next supply chain attack: Lessons from the tj-actions/changed-files Incident

Matan Giladi
Security Researcher
Published March 17 2025 · 4 min. read

The recent compromise of the tj-actions/changed-files repository on March 14 caused significant security concerns. Now that the vulnerability was mitigated, the focus turns to preventing future incidents. 

What happened?

A personal access token (GitHub PAT) of an overly permissioned account was compromised, pushed a malicious commit to the tj-actions/changed-files repository, and repointed all existing tags to it. This exposed any GitHub secrets referenced in workflows invoking this action in logs. If those logs were public or accessible, sensitive credentials such as GitHub tokens and cloud access keys may have been compromised.

The vulnerability introduced by the malicious code, identified as CVE-2025-30066, was mitigated when the malicious script got deleted. Repositories in risk were those that referenced secrets alongside the compromised action in the same workflow file, were updated after the breach (otherwise exposure likelihood was very low), and were public or had the relevant workflow logs exposed somewhere. This accounts to a total of 340 repositories that got exposed to the risk (as gathered by this script).

Since then, Adnan Khan, who warned about such breach in ts-actions/changed-files over a year ago, discovered a related incident in a fork of reviewdog/action-setup, a transient dependency of the ts-actions/changed-files. The v1 tag, originally pointing to an old 2020 version, pointed to the fork’s malicious commit for two hours on March 11, 2025. No public repositories were found to use the infected tag. The short risk window and the long unused version make any compromise very unlikely. This incident is now tracked as CVE-2025-30154.

If you haven’t already, map all instances of both actions in your environments, check for any secrets referenced in those workflow files, and verify for leakage. If exposed, rotate them immediately.

How can we prevent similar incidents in the future?

One possible solution is to pin actions to specific commit hashes. Enforcing this globally across the organization ensures that only verified versions of the actions are used, instead of automatically pulling unverified updates. However, this solution has several caveats:

  1. Limited Coverage: It only prevents malicious code coming through GitHub actions. There are many other ways malicious code can infiltrate systems. Past incidents have shown attacks through backdoored release tarballs (e.g., the xz backdoor), hijacked CDN entries (e.g., the Polyfill incident), compromised npm packages (e.g., the @solana/web3.js infection), and more.
  1. Reactive Security: A focus on shutting one hole at a time doesn’t cut it. As new vulnerabilities are discovered faster than old ones are patched, shifting to proactive security is crucial.
  1. Scalability Issues: While pinning actions to specific commit hashes can scale technically, it is likely to face significant pushback across organizations. It could break existing workflows and cause conflicts between development and security teams.
  1. Partial Protection: While it helps prevent malicious updates, pinning actions doesn’t mitigate pre-existing malicious code.

Beyond pinning actions, maintaining a healthy application security posture is seriously crucial in this area. You need the ability to immediately alert teams to any infected versions across the entire supply chain—from code to runtime. You need to detect exposed secrets globally, which is essential to prevent leaks of sensitive credentials. This is typically solved with an ASPM tool, as they are designed for such needs. Runtime detection is a good layer of defense in depth, but it’s generally preferable to first prevent incidents before they starts running.

Zero-Trust Code Management: The ultimate defense

Ultimately, the most robust defense against such incidents is zero-trust code management. This approach ensures that no code component is trusted until its safety has been verified, whether that code comes from an external library, an internal repository, or a public source.

For malicious code detection, the solution must be precise, with minimal false positives and minimal false negatives. This detection process should be flexible enough to be integrated at various entry points in the supply chain and must be a prerequisite before any code is pulled into the environment.

A month ago, Apiiro released open-source tools designed for this very purpose. These tools were developed based on research that identifies two patterns common in malicious code but rare in benign code: dynamic code execution and obfuscation. The recent incident is a textbook example of these patterns, both of which are detectable using these tools out of the box.

A practical workflow for safer GitHub actions

The secure way to handle GitHub Actions, and by extension, any software dependencies and any unfamiliar code—follows this simple process:

  1. Scan the code for vulnerabilities and malicious payloads before using them in your own code.
  1. If the scans pass, pin the action to the specific commit hash that was verified.

The malicious code detection part can be done using our recently published open-source malicious code detection ruleset. Users who followed this workflow would not have been affected by this incident.

PRevent: Detection and prevention for your codebase

To get broad protection, not only against the specific use case of malicious code in actions, and not only in the rare case that it’s possible to enforce actions pinning globally, a good starting point is protecting your codebases using PRevent, a fully controlled GitHub app that detects and blocks malicious code. If the affected repository had been using PRevent, this incident would have been entirely prevented, automatically.

The malicious commit, as caught when added to a repo monitored by PRevent, using the ruleset (comments can be disabled for stealth and email alerts can be enabled):

PRevent blocks the commit, and triggers code reviews (customizable):

Bottom Line

CVE-2025-30066 highlights the ongoing risks of supply chain attacks and the limitations of reactive security measures. While pinning dependencies helps reduce exposure, it doesn’t address the broader challenge of detecting and preventing malicious code at scale. A zero-trust approach to dependency management is essential. Every component must be verified before use, and proactive detection should be built into the development pipeline. With the right tooling, such as open-source malicious code detection and automated enforcement, organizations can move beyond patching individual incidents to systematically preventing them.

How Can Apiiro Help?

A strong application security posture is key to effective incident response. You need instant visibility across your entire software supply chain, along with full context to assess impact, necessary details, and act decisively. A contextual code-to-runtime ASPM platform like Apiiro delivers exactly that:

Efficient response also requires real-time alerting to the right personnel, automated workflows and policies enforcement, and most critically—comprehensive secret exposure management to prevent credential leaks:

Runtime detection is another valuable layer of defense, but the priority should first be on detecting and preventing incidents before execution, rather than relying on runtime detection to block attacks at the last moment.