In mid-March 2025, one of the most widely used GitHub Actions in the open-source ecosystem turned against the very pipelines that trusted it. CVE-2025-30066 describes a supply chain compromise of tj-actions/changed-files, a GitHub Action used by an estimated 23,000+ repositories to detect which files changed in a pull request or push. An attacker gained the ability to rewrite the action's git tags, pointing dozens of previously "safe" version references at a single malicious commit that dumped runner memory and printed CI/CD secrets — plaintext tokens, cloud credentials, npm and PyPI keys — directly into public workflow logs. Anyone who ran an affected workflow during the compromise window may have had secrets exposed to anyone who could view the build output.
This is a textbook example of a supply chain attack against CI/CD infrastructure, and it's a useful case study for why pinning, log hygiene, and least-privilege secrets handling in GitHub Actions are no longer optional hardening steps — they're baseline requirements for a trustworthy CI pipeline.
What CVE-2025-30066 Actually Did
tj-actions/changed-files is a convenience action: workflows call it to get a list of files touched by a commit or PR, then conditionally run lint, test, or deploy steps against just those files. Because it's a low-risk-looking utility action, it was pinned loosely by many consumers — by major version tag (v45, v44, etc.) or even a floating major tag — rather than by immutable commit SHA.
The attacker compromised the project's release tooling and force-pushed a malicious commit, then retroactively repointed the existing version tags to reference it. Any workflow that referenced tj-actions/changed-files by tag — which was the vast majority of consumers, since tag-based referencing is the pattern GitHub's own documentation encourages for readability — silently began pulling the compromised code on its next run, with no diff in the calling workflow to review.
The injected payload downloaded a further-staged script that scraped the GitHub Actions runner's process memory for secrets, base64-encoded whatever it found, and echoed it into the workflow's own build log. In public repositories, those logs are visible to anyone; in private repositories, anyone with read access to Actions logs could see the dump. No exfiltration to an attacker-controlled server was required for the compromise to succeed — the CI pipeline's own logging infrastructure did the exfiltration for them, which is part of what made this both effective and hard to detect with typical network egress monitoring.
Affected Versions and Components
- Component:
tj-actions/changed-files(GitHub Marketplace Action) - Affected versions: All tagged releases were affected, because the compromise worked by rewriting existing tags rather than shipping a new version. Any workflow referencing the action by a version tag (e.g.,
tj-actions/changed-files@v45) rather than a pinned commit SHA could have pulled the malicious commit during the exposure window. - Downstream exposure: Any GitHub Actions workflow — across public and private repositories — that invoked the action during the compromise window and had secrets available to the job (via
secrets.*, environment variables, or inherited organization/repository secrets) was at risk of having those secrets printed into its own logs. - Related compromise: Security researchers tracing the intrusion found ties to an earlier compromise of
reviewdog/action-setup(tracked separately as CVE-2025-30154), which is believed to have been an entry point that led to the compromise of credentials used to publishtj-actions/changed-files. The two incidents together illustrate how a single leaked GitHub token or personal access token can cascade across the Actions ecosystem, since many popular actions share maintainers, CI bots, or dependencies.
CVSS, EPSS, and KEV Status
NVD scored CVE-2025-30066 as High severity, reflecting the network-exploitable, no-privilege, no-user-interaction path to widespread confidentiality impact across dependent CI/CD environments — consistent with a vulnerability capable of leaking credentials at scale with essentially no attacker cost per victim once the tags were repointed.
Given the scope of exposure and the speed at which it was weaponized against real pipelines, CISA added CVE-2025-30066 to its Known Exploited Vulnerabilities (KEV) catalog within days of public disclosure, requiring remediation by federal civilian agencies on an accelerated timeline. KEV inclusion this quickly is uncommon for a build-tooling issue and underscores how seriously the incident was treated — it wasn't theoretical risk, it was confirmed active exploitation against production CI pipelines. EPSS scoring for the CVE has moved over time as exploitation data has been incorporated, but the more decisive real-world signal here was the KEV listing itself, plus the direct confirmation from multiple organizations that they found their own secrets printed in affected build logs.
Timeline
- Prior weeks:
reviewdog/action-setupis compromised (CVE-2025-30154), reportedly providing the attacker a foothold that led to credentials for other actions in the ecosystem. - March 14, 2025: Security researchers, including the team at StepSecurity, detect anomalous network and process behavior in workflows using
tj-actions/changed-filesand identify a malicious commit that dumps runner memory to logs. The finding is disclosed publicly and to GitHub. - March 14–15, 2025: GitHub and the
tj-actionsmaintainer respond, removing the malicious commit, restoring all version tags to point at known-clean commits, and temporarily pulling visibility of the action while the incident is investigated. GitHub Marketplace listing is affected during remediation. - March 15, 2025: CVE-2025-30066 is assigned and published, documenting the compromise and its impact on downstream CI/CD secrets.
- March 18, 2025: CISA adds CVE-2025-30066 to the KEV catalog, formally recognizing active exploitation and setting a mandatory remediation deadline for federal agencies.
- Following weeks: The maintainer publishes guidance recommending consumers pin the action by commit SHA rather than tag, and the broader GitHub Actions security community renews calls for SHA pinning as a default practice across the ecosystem.
Remediation Steps
If your organization used tj-actions/changed-files in any workflow around mid-March 2025, treat this as an active incident until proven otherwise, not a routine dependency bump:
- Audit workflow history. Search all repositories (including forks and archived-but-active ones) for references to
tj-actions/changed-filesand identify every workflow run that executed during the compromise window. - Assume secret exposure and rotate. Any secret available to an affected job — GitHub tokens, cloud provider credentials, package registry tokens, database connection strings, signing keys — should be treated as exposed and rotated. Don't rotate selectively based on "likely" impact; the memory dump technique doesn't discriminate.
- Scrub logs. Review and purge historical Actions logs that may contain printed secrets, and check whether any of those logs were publicly visible (public repo) or accessible to a broader internal audience than intended.
- Pin third-party actions by commit SHA, not tag. This is the single most effective mitigation against this entire class of attack. A pinned SHA (
uses: tj-actions/changed-files@<full-commit-sha>) cannot be silently repointed the way a mutable tag likev45can. - Restrict secret availability to the minimum necessary. Avoid passing broad, long-lived secrets into jobs that invoke third-party actions when a scoped, short-lived token would do. Use environment protection rules and
permissions:blocks to shrink the blast radius of any single compromised action. - Monitor for anomalous action behavior. Unexpected network calls, unfamiliar base64 blobs in logs, or actions reaching out to non-standard endpoints are all signals worth alerting on inside the CI pipeline itself, not just at the network perimeter.
- Maintain an SBOM/inventory of CI dependencies. Knowing exactly which third-party GitHub Actions your workflows depend on — including transitive ones pulled in by composite actions — is what makes an incident like this answerable in hours rather than days.
How Safeguard Helps
Incidents like CVE-2025-30066 expose a blind spot most security programs haven't fully closed: the software supply chain that builds your software is itself part of your attack surface, and GitHub Actions workflows are prime real estate for that risk. Safeguard is built to close that gap.
Safeguard continuously inventories the third-party GitHub Actions, container images, and build-time dependencies used across your CI/CD pipelines, so when a compromise like this one surfaces, you get an immediate, accurate answer to "are we affected?" instead of a multi-day manual grep across every repository. Our platform flags workflows that reference actions by mutable tags instead of pinned commit SHAs, surfaces overly broad secret scoping in job definitions, and detects anomalous behavior patterns — like credential-shaped strings appearing in build logs — before they turn into a full breach disclosure.
Because Safeguard tracks CVE and KEV data continuously and correlates it against your actual dependency graph, when the next tj-actions-style compromise happens, you'll know within minutes which pipelines used the affected component, which secrets need rotating, and which workflows need to be paused — turning what was, for many teams in March 2025, a scramble through commit history into a routine, contained response.