mythsthe platformstj-actions/changed-files2025software supply chain / ci/cd

everyone assumed:

a popular open-source CI helper is too widely-used to be risky

what was actually true:

Pinning to a version tag trusts that the tag will keep pointing where it pointed.

how it happened

  1. whoattackercompromised the action
  2. the gappinned versionspointed at malicious code
  3. the result23,000+ repositoriestokens and keys exposed
the gap that let it happen the result

what everyone assumed

Popularity reads as a safety signal. A component used by tens of thousands of repositories has had thousands of eyes on it, so the risk has been found by now and you are not the one discovering it the hard way. Pinning to a version adds a second layer: even if the upstream changes, you stay on the code you reviewed. It is a careful belief, held by careful engineers.

what happened

On 14 and 15 March 2025, the action’s repository was compromised, and the attacker rewrote the existing version tags to point at a malicious commit. This is the part that retired the assumption: rewriting the tags meant that even pinned versions resolved to the new code. The injected script read secrets out of the runner process and printed them into the workflow logs. On repositories with public logs, those secrets were now sitting in plain view, written there by the build itself.

step by step

  1. teams pin the action to a version tagWorkflows reference tj-actions/changed-files by a version tag, trusting it to stay on reviewed code.
  2. 14-15 March 2025the action's repository is compromisedThe attacker gets write access to the upstream project.
  3. existing version tags are rewrittenThe old tags now point at a malicious commit, so pinned workflows pull the new code without any change on their side.the assumption breaks here
  4. the script prints secrets into build logsIt reads secrets out of the runner process and writes them into the workflow output. Public logs put them in plain view.
  5. disclosed within days, CVE-2025-30066More than 23,000 repositories ran it. The fix is to upgrade past the tampered tags and rotate every secret the pipeline could have printed.

how it surfaced

The compromise was caught and disclosed within days, but by then the malicious code had moved through more than 23,000 repositories. Exposed material included access keys, GitHub personal access tokens, npm tokens, and private keys. CISA added CVE-2025-30066 to its Known Exploited Vulnerabilities catalog. The fix was to upgrade past the tampered tags and rotate every secret the pipeline could have printed.

Pinning to a version tag trusts that the tag will keep pointing where it pointed.

A tag is a label the upstream can move, so the only pin that holds through a repository takeover is one to an immutable commit hash.

picture it at a company like yours

The company here is made up. The other two paths are not: they happened, and each links to the story.

your company
a normal dayYour developers use a popular open-source helper in every build.
the gap nobody seesThey point to it by version name, which the owner can change.trusting what a supplier ships
  1. in this story
    the day it mattersThe helper is hijacked and the version names now point to malicious code.
    what it costs youYour build prints your secret keys into logs anyone can read.
  2. or it goes like this
    howA genuine, signed update from a certified vendor carries a backdoor.
    what leavesa quiet way into your networkwho ends up with ita state intelligence service
    it happenedSolarWinds / Sunburst, 2020
  3. or it goes like this
    howA script your site loads from elsewhere changes owner.
    what leavesyour visitors' safetywho ends up with itthe new owner of the script
    it happenedPolyfill.io, 2024

sources

  1. GitHub Action Compromise Puts CI/CD Secrets at Risk in Over 23,000 Repositories (The Hacker News) ,
  2. Supply Chain Compromise of Third-Party tj-actions/changed-files (CVE-2025-30066) (CISA) ,
  3. GitHub Action tj-actions/changed-files supply chain attack (Wiz) ,

← all myths

your turn

what you can do about it

  1. this week

    Open one workflow file and check whether its actions point at version tags or at full commit hashes.

    Your CI pipeline runs third-party actions you did not write, with access to secrets you would not paste anywhere by hand. The question the quiet months ask is whether those dependencies are pinned to something that cannot be moved out from under you. The tj-actions secrets reached daylight through exactly the gap between those two.

  2. go deeper

  3. if you're not sure where to start

    Run the offboarding checklist on one leaver. It covers every account and token to close when someone leaves.

    open the checklist →

the letter · every two weeks

one access gap in your inbox, with the fix.

Every issue takes one way access creeps in, shows a real incident where it went wrong, and ends with one thing to check that week. Written for the people who run the tools, without a security team behind them.

  • 1one mechanism, explained plainly
  • 2one real incident, taken apart
  • 3one step you can take on Monday

get the next issue

One email every two weeks. Your address stays here and is never passed to vendors. One click to unsubscribe. Privacy.