Safeguard
DevSecOps

What is CI/CD Pipeline Poisoning

CI/CD pipeline poisoning lets attackers hijack your build automation to steal secrets and plant backdoors. Here's how it works and how to stop it.

Priya Mehta
DevSecOps Engineer
7 min read

On March 14, 2025, maintainers discovered that tj-actions/changed-files — a GitHub Action used in over 23,000 repositories — had been tampered with. A malicious commit caused CI runners to dump their memory into public workflow logs, exposing secrets like AWS keys, npm tokens, and GitHub PATs for anyone who scrolled far enough. That incident is a textbook case of CI/CD pipeline poisoning: an attack that targets the automated build, test, and deployment pipeline itself rather than the application code it ships. Instead of hunting for a bug in a library, attackers inject malicious steps, tamper with build scripts, or hijack a trusted third-party action so the pipeline does the dirty work — stealing secrets, planting backdoors in build artifacts, or signing malware with the organization's own credentials. Because pipelines run with elevated, often lightly monitored privileges and touch every release, a single poisoned job can compromise every downstream customer who installs the resulting package. Here's how the attack works, what it has already broken, and how to catch it before it ships.

What Is CI/CD Pipeline Poisoning?

CI/CD pipeline poisoning is an attack technique where an adversary modifies the automation that builds, tests, or deploys software so that it executes attacker-controlled logic instead of, or in addition to, the intended build steps. Security researchers at Cider Security formalized this in 2022 as part of the OWASP Top 10 CI/CD Security Risks, splitting it into two categories under CICD-SEC-4 ("Poisoned Pipeline Execution"). Direct Poisoned Pipeline Execution (D-PPE) happens when an attacker with write access — a compromised contributor account, a leaked SCM token — edits pipeline definitions directly, such as a .github/workflows/*.yml file or a Jenkinsfile. Indirect Poisoned Pipeline Execution (I-PPE) is subtler: an attacker without direct write access gets the pipeline to run their code anyway, typically by opening a pull request from a fork that triggers a privileged workflow, or by manipulating a build script, Makefile, or test fixture that the pipeline executes without question. Cider Security was acquired by Palo Alto Networks in October 2022 for a reported $195 million, a signal of how seriously the market took this risk category once it was named.

How Do Attackers Actually Poison a Pipeline?

Attackers poison pipelines through four primary vectors: compromised third-party actions, malicious pull requests, stolen CI credentials, and tampered build caches or dependencies. The tj-actions incident illustrates the first: the attacker gained access to a maintainer's personal access token, then retagged existing version tags (like v35) to point at a new malicious commit — meaning every repository pinned to a version tag rather than a commit SHA silently pulled the compromised code on its next run. Malicious pull requests exploit workflows like pull_request_target or misconfigured workflow_run triggers, which execute with the base repository's secrets even though the code under test came from an untrusted fork — a class of bug researchers nicknamed "pwn requests" when GitHub Security Lab documented it in 2021. Stolen CI credentials come from phishing, malware on a developer laptop, or leaked tokens in logs, and hand attackers the same access the legitimate pipeline has: cloud deploy keys, package registry publish tokens, container registry push access. Tampered dependencies and caches — as seen in the Ultralytics YOLO incident on December 4, 2024, where a compromised GitHub Actions cache let attackers inject a cryptomining payload into PyPI release 8.3.41 — poison the pipeline's inputs rather than its config, achieving the same result.

What Real-World Incidents Show This Isn't Theoretical?

Four incidents across five years show pipeline poisoning moving from novel to routine. SolarWinds' Orion platform was compromised starting around September 2019, when attackers inserted the Sunspot malware into the build server to replace source files during compilation; the trojanized update, dubbed Sunburst, was downloaded by roughly 18,000 customers before Microsoft, FireEye, and SolarWinds disclosed it in December 2020. The Codecov Bash Uploader script was modified on January 31, 2021, after attackers exploited an error in Codecov's Docker image creation process to extract credentials and alter the script; the tampering exfiltrated CI environment variables — often containing cloud keys and source-control tokens — from an unknown number of customer pipelines for roughly two months before a customer reported it on April 1, 2021. CircleCI disclosed on January 4, 2023, that malware on an engineer's laptop had stolen a session token that bypassed two-factor authentication, granting access to production systems; CircleCI told all customers to rotate every secret stored in the platform, regardless of whether their specific pipeline was touched. And the tj-actions/changed-files compromise in March 2025 shows the pattern hasn't slowed — it hit a broader base (23,000+ repos) using a simpler technique (a retagged Git reference) than any of the prior three.

Why Are CI/CD Systems Such High-Value Targets?

CI/CD systems are high-value targets because they hold the credentials needed to reach production while typically receiving far less security scrutiny than production itself. A single pipeline often has npm or PyPI publish tokens, container registry push access, cloud deployment roles, and code-signing keys all reachable from the same job — a concentration of privilege that would trigger review if requested for a production service account but is frequently granted to CI by default. Pipelines also multiply blast radius: a compromised production server affects one environment, but a compromised build pipeline affects every artifact it produces afterward, and every customer who installs that artifact. That's why SolarWinds' single build-server compromise reached an estimated 18,000 organizations, and why the U.S. government's response — Executive Order 14028 in May 2021 — explicitly called out software supply chain integrity and SBOM requirements as a national security matter, not just a vendor hygiene issue.

How Can Security Teams Detect and Prevent Pipeline Poisoning?

Security teams can materially cut this risk with five specific controls, most of which are configuration changes rather than new tooling. First, pin third-party GitHub Actions and CI plugins to an immutable commit SHA instead of a mutable version tag — this alone would have stopped the tj-actions retag attack from silently propagating. Second, enforce least privilege on CI tokens by scoping GITHUB_TOKEN and equivalent credentials to read-only by default and granting write or deploy scopes only to the specific jobs that need them. Third, isolate untrusted input: disable or tightly restrict pull_request_target and workflow_run triggers on repositories that accept external contributions, and require maintainer approval before first-time contributors' workflows run. Fourth, treat pipeline configuration files as production code — require code review on changes to .github/workflows/, Jenkinsfile, .gitlab-ci.yml, and equivalent files, and alert on out-of-band edits. Fifth, generate and diff a Software Bill of Materials (SBOM) on every build so an unexpected new dependency, transitive package, or build-time artifact shows up as a detectable change rather than disappearing into a release.

How Safeguard Helps

Safeguard gives security teams the visibility a poisoned pipeline is built to evade. Griffin AI continuously analyzes pipeline configurations, third-party action usage, and dependency changes across your SCM and CI systems, flagging unpinned actions, newly added build steps, and anomalous permission grants before they merge. Reachability analysis cuts through alert noise by confirming whether a vulnerable or newly introduced dependency is actually exercised in your build or runtime path, so teams triage the handful of findings that matter instead of every CVE in the tree. Safeguard generates SBOMs automatically on every build and can ingest existing SBOMs from your pipeline, giving you a diffable record of exactly what changed between releases — the same visibility that would have surfaced Sunburst or the Ultralytics cache-poisoning payload sooner. When Safeguard finds a fixable issue, it opens an auto-fix pull request with the corrected dependency version or configuration, so remediation ships as fast as the vulnerability was found.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.