FALCONINTERNET

Cordyceps: The CI/CD Flaw That Could Poison the Code You Trust

Security
Cordyceps: The CI/CD Flaw That Could Poison the Code You Trust

Last week, researchers at Novee Security published findings from a months-long audit of open-source CI/CD pipelines. They named the vulnerability class Cordyceps — after the parasitic fungus that hijacks its host's nervous system and steers it somewhere it never intended to go. The flaw lets an anonymous attacker with a free GitHub account quietly redirect a privileged automation pipeline, then disappear before anyone notices.

Over 300 repositories confirmed fully exploitable out of roughly 30,000 scanned. Affected projects included Microsoft Azure Sentinel, Google's AI Agent Development Kit, the Cloudflare Workers SDK, Apache Doris, Python's Black code formatter, and LLVM. No credentials required, no org membership — just a pull request or comment crafted to cross the right trust boundary at the right moment.

The Trust Boundary Nobody Audited

The root cause isn't a single bug in a single file. It's an architectural pattern that looks safe at every individual step but is exploitable when you trace the full chain. A low-privilege workflow — one that handles pull requests from untrusted contributors — passes its output to a high-privilege workflow that has write access to the repository, publishing rights to npm or PyPI, or owner-level credentials to a cloud account. Each step appears entirely normal. The danger lives only in their composition.

Novee identified four attack classes within this pattern: command injection (attacker-controlled PR branch names or comment text interpolated directly into shell commands), code injection (user input fed into JavaScript evaluated at runtime via actions/github-script), broken authorization (approval logic that fails silently due to logic bugs rather than a missing check), and cross-workflow privilege escalation (data flowing from a sandboxed job into one holding cloud-admin tokens). The dangerous GitHub Actions triggers are pull_request_target and workflow_run — legitimate features that become a liability when they process attacker-controlled data in a privileged context.

The research team scanned roughly 30,000 high-impact repositories. They flagged 654 as suspicious and confirmed 300+ as fully exploitable — meaning a proof-of-concept attack ran to completion, not just that a pattern matched a lint rule.

What Attackers Could Have Done

Validated compromises would have allowed: poisoning packages on npm, PyPI, Docker Hub, and Helm; pushing code directly to protected branches; forging CI check results; and stealing long-lived cloud credentials. In the Microsoft Sentinel case, a crafted PR comment could exfiltrate a non-expiring GitHub App key — persistent write access to security content deployed into customer environments. In the Google ADK case, a single pull request was enough to grant the attacker roles/owner in Google Cloud. The Cloudflare Workers SDK and Python's Black formatter each get installed millions of times per month; a poisoned release from either would have propagated silently before anyone noticed.

Why Your Scanner Didn't Catch It

Standard SAST tools and dedicated GitHub Actions scanners analyze one file at a time. Cordyceps-class vulnerabilities don't exist in any single file — they live in the data flow between files. A tool reading build.yml in isolation won't see that the artifact it writes gets picked up and executed by publish.yml with a token that has package-publish rights. Until tooling catches up to cross-workflow analysis, these chains are effectively invisible.

There's an additional compounding factor: AI coding assistants. When developers use AI tools to generate GitHub Actions configuration, those tools reproduce the same insecure patterns over and over — because that's how the internet wrote CI/CD configs for years. Novee flagged this directly: the same class of vulnerability is being quietly planted across millions of repositories, one AI-generated config file at a time.

What This Means If You Don't Write CI/CD Configs

Most small and mid-size businesses don't run GitHub Actions directly. But that doesn't put them outside the blast radius. If your site runs WordPress, a Node.js app, a Python backend, or any modern web stack, it almost certainly depends on packages distributed through npm, PyPI, or similar registries. Those packages come from projects that do run GitHub Actions. If a Cordyceps-class flaw in an upstream pipeline had been exploited before disclosure, a poisoned package update could have arrived in your next npm install or pip install — and your own automated deploys would have pulled it in without a second look.

For teams that do use GitHub Actions for their own deploys: audit your workflows now. If any workflow uses pull_request_target or workflow_run and processes external data, it deserves a close read. Use pull_request (not pull_request_target) for building PR code. Set permissions: contents: read as the workflow default. Grant write permissions only to the specific jobs that need them. Pin third-party actions to full commit SHAs, not floating tags. Require CODEOWNERS review for any change to .github/workflows/.

GitHub has already moved: actions/checkout v7 ships with secure-by-default behavior, and on July 16, 2026, GitHub will backport enforcement logic to all currently supported major versions. Workflows pinned to floating tags like actions/checkout@v4 will automatically inherit the safer defaults. That's a meaningful platform-level fix — though it addresses the checkout surface, not every cross-workflow trust boundary.

Cordyceps is humbling because there's no single file to patch, no CVE to track. The flaw is systemic — a failure to reason about trust across automation steps that no single engineer owned end to end. At Falcon Internet, it reinforces why dependency pinning and pipeline hygiene are drilled into how we manage hosted applications. The supply chain upstream is large, fast-moving, and not always audited as carefully as it looks.

Need this handled instead of explained?

We do this for a living — talk to an engineer about your setup.