In March 2025, attackers compromised the popular tj-actions/changed-files GitHub Action, a dependency used by more than 23,000 repositories, and rewrote its code to dump CI runner memory — including AWS keys, GitHub tokens, and npm publishing credentials — directly into build logs. The incident, tracked as CVE-2025-30066, is the clearest recent proof that CI/CD pipelines have become a primary attack surface rather than a peripheral one. Pipelines hold the credentials that matter most: cloud provider keys, signing certificates, registry tokens, and access to every downstream repository a build touches. Attackers have noticed. Sonatype's 2024 State of the Software Supply Chain report counted more than 512,000 malicious open-source packages discovered that year, and a growing share were built specifically to execute inside CI runners rather than production code. This piece breaks down the current CI/CD pipeline security vulnerability trends, the incidents driving them, and how to catch them before they reach a build.
What counts as a CI/CD pipeline security vulnerability?
A CI/CD pipeline security vulnerability is any weakness in the build, test, or deploy chain that lets an attacker inject code, steal credentials, or tamper with an artifact before it ships. The OWASP-adjacent Top 10 CI/CD Security Risks framework (originally published by Cider Security in 2022) groups these into ten categories, and four show up in nearly every real-world breach: Poisoned Pipeline Execution (CICD-SEC-4), where an attacker modifies pipeline definitions or scripts to run malicious commands; Dependency Chain Abuse (CICD-SEC-3), where a compromised third-party action, package, or plugin executes with pipeline-level trust; Insufficient Credential Hygiene (CICD-SEC-6), where long-lived secrets sit in environment variables readable by any step; and Insufficient Logging and Visibility (CICD-SEC-10), where teams have no record of what a build actually did. The tj-actions incident touched three of the four at once: a poisoned third-party action, weak credential hygiene, and logs that became the exfiltration channel rather than a detection tool.
How many CI/CD-related supply chain attacks were disclosed in 2024 and 2025?
At least three major, independently confirmed incidents landed in a 15-month span, up from roughly one per year earlier in the decade. In December 2024, the Ultralytics YOLO package on PyPI was compromised through a GitHub Actions cache-poisoning flaw, letting attackers slip a cryptomining payload into versions 8.3.41 and 8.3.42 before maintainers caught it. In March 2025, the tj-actions/changed-files compromise (CVE-2025-30066) affected over 23,000 repositories, and the closely related reviewdog/action-setup action was compromised through the same actor days earlier, showing the attack moved laterally through the GitHub Actions ecosystem rather than hitting one target. GitGuardian's 2024 State of Secrets Sprawl report separately found 12.8 million new secrets exposed in public GitHub commits during 2023 alone, a large share of them CI/CD-related tokens (AWS, npm, Docker Hub) that would grant an attacker the same access a poisoned pipeline would. The pattern is consistent: pipelines are being targeted for the credentials and blast radius they provide, not just for the code they build.
What actually happened in the tj-actions/changed-files compromise?
Attackers gained write access to the reviewdog/action-setup repository, which tj-actions/changed-files referenced, and used it to push a malicious commit that force-updated every version tag of tj-actions/changed-files — including tags like v35 and v44 that thousands of workflows pinned to by name rather than by commit hash. Because GitHub Actions resolves tag references at run time, every pipeline that referenced tj-actions/changed-files@v35 (instead of a fixed SHA) pulled the malicious version on its next run without any code change of its own. The injected script downloaded a Python payload that scanned CI runner memory for anything resembling a secret, base64-encoded it, and printed it to the workflow's build log — a log visible to anyone with read access, including the public in open-source repositories. StepSecurity identified the anomaly on March 14, 2025, and GitHub temporarily removed the action from the Marketplace and disabled the repository the same week. No confirmed downstream credential misuse from the exposed secrets was publicly reported, but the exposure window meant any organization running the action needed to treat every secret used in that pipeline as compromised and rotate it.
Why are self-hosted GitHub Actions runners a growing risk?
Self-hosted runners expand the CI/CD attack surface because they give a workflow — and anything that can inject code into it — direct access to whatever network, filesystem, and credentials the runner's host machine has, unlike GitHub's disposable hosted runners. PyTorch's nightly build pipeline demonstrated this on December 30, 2022: attackers exploited a dependency confusion flaw, publishing a malicious package named torchtriton to the public PyPI index with a higher version number than the legitimate internal package of the same name. Because PyTorch's self-hosted runner installed dependencies without namespace isolation, it pulled the attacker's package instead, which then exfiltrated SSH keys, environment variables, and other data from the runner host. PyTorch disclosed the incident and reserved the torchtriton name to prevent repeat attacks, but the underlying lesson generalized: any self-hosted runner that resolves public package names without a private index or scoped namespace is one dependency confusion attack away from full host compromise.
What role do vulnerabilities in the CI/CD platforms themselves play?
Beyond supply chain poisoning, unpatched flaws in the CI/CD tools organizations run in-house remain one of the most exploited categories, and Jenkins is the clearest current example. CVE-2024-23897, disclosed January 24, 2024, is an arbitrary file-read vulnerability in Jenkins' built-in CLI command parser that affects every Jenkins version prior to the fix and requires no authentication to exploit against instances with anonymous read access. Attackers used it to read credentials, SSH keys, and source code directly off the Jenkins controller, and CISA added it to its Known Exploited Vulnerabilities catalog within weeks of disclosure because active exploitation in the wild was already confirmed. GitLab's CVE-2021-22205, an unauthenticated remote code execution flaw in image file processing, saw similar mass exploitation years after a patch was available, because internet-facing GitLab and Jenkins instances are frequently left unpatched long past their disclosure date. Platform CVEs like these matter as much as supply chain attacks because they hand an attacker the same prize — pipeline-level access — without needing to compromise a single dependency.
How can security teams detect CI/CD vulnerabilities before they ship?
Security teams close most of this exposure by pinning, scoping, and watching what a pipeline is actually allowed to do, rather than trusting what it's labeled to do. Pinning third-party actions and packages to an immutable commit SHA instead of a mutable tag would have prevented the tj-actions tag hijack from silently propagating. Replacing long-lived cloud and registry secrets with short-lived OIDC tokens scoped to a single workflow run removes the exact credential type both the tj-actions and PyTorch attackers went after. Restricting self-hosted runners to private repositories and isolating them from production networks limits the blast radius when a runner is compromised. Generating a software bill of materials (SBOM) for every build and diffing it against the previous one surfaces a swapped or newly introduced dependency, like torchtriton, before it reaches production. And keeping CI/CD platforms like Jenkins and GitLab patched against known-exploited CVEs, rather than patching on a quarterly cycle, closes the window CVE-2024-23897 depended on.
How Safeguard Helps
Safeguard gives security teams the visibility these incidents exposed as missing. Reachability analysis determines whether a vulnerable dependency or compromised action is actually invoked in your build and runtime paths, so teams triage the next tj-actions-style disclosure by real exposure instead of scanning every repository that merely lists it. Griffin AI correlates pipeline configuration, dependency graphs, and CVE feeds to flag risky patterns — tag-pinned third-party actions, over-privileged self-hosted runners, stale platform versions — before they're exploited. Safeguard generates and ingests SBOMs on every build to detect dependency swaps and drift in near real time, and its auto-fix PRs open the exact diff needed to pin an action to a commit SHA, bump a patched platform version, or rotate an exposed secret reference, cutting remediation time from weeks to minutes.