Cordyceps and the pipeline attack surface we keep ignoring
Tomás Vega
A build server you did not ask to be exposed
Your CI system runs untrusted code, holds long-lived credentials, and pushes to production. It is a build tool, we agreed. Sit with that framing for a second.
This week Novee Security disclosed a CI/CD flaw pattern they call Cordyceps. Per The New Stack's coverage on July 1, the pattern lets an unauthenticated actor plant self-propagating triggers across pipelines. That is the hook. Not a single vendor bug. A shape.
We have seen this movie before. Reused build tokens. Webhook endpoints that accept anything wearing the right hat. Runners with more privilege than the human who wrote the code they are executing. Cordyceps is another data point on the same line.
"Part of the attack surface" is not a rhetorical flourish
CI/CD has spent a long time being described as internal plumbing. Runners live in a "trusted" VPC. The token in your deploy job is fine, because only maintainers can touch it. Pull-request previews are safe, because they run in a sandbox. Right?
Every one of those assumptions dies the first time an unauthenticated trigger fires. And that is the substance of the Novee disclosure as reported: unauthenticated. No login. No leaked key. You do not compromise the pipeline in the classical sense. The pipeline arrives to help.
The New Stack's framing is that CI/CD is part of every product's attack surface. Correct, boring, and still not how most orgs behave. Look at your last threat model. Did the runner get its own row?
What changes for those of us who have to maintain this
Be honest about what a disclosure like this can and cannot do.
It cannot patch a category. Cordyceps is a pattern, per the coverage. Patterns get partially mitigated by one platform, ignored by another, and rediscovered under a new name some months later. If you are waiting for a single CVE that fixes it, keep waiting.
What it can do is win you an internal argument. The next time somebody objects to a security control on the pipeline because "the runner is behind the firewall", you have a named, current example to put on the slide. Use it.
Things worth revisiting this quarter, none of them new, all of them still unfashionable:
- Which triggers on your CI accept payloads before any authentication? Public webhooks count. So do "verified" ones where verification is a shared secret in an environment variable nobody remembers setting.
- Which runner has permissions its workload does not need? A runner that can push to any branch, mint any short-lived token, or reach production over a flat network is a fine foothold. Calling it a build tool does not change what it is.
- Which build tokens are minted once for a whole org and reused across jobs? Every reuse copies the blast radius.
- Which pipeline can trigger another pipeline? The "self-propagating" adjective in the disclosure is doing a lot of work. Answer that question in your own topology before someone else does.
Signed. Verified. Still exploitable, if the trigger that fires the signature dance is one an unauthenticated actor can send. Provenance closes fewer doors than the marketing suggests.
The verdict
Cordyceps as a specific finding may fade. The reason for its existence will not. Pipelines run untrusted code and hold the credentials to reach production. We keep pretending they are a slightly weirder Make.
The New Stack got the framing right. Your CI is on the attack surface. Whether you treat it that way is a scheduling problem, not a knowledge problem.
Novee has done the boring work of publishing another example. Your job is to notice, and to write down which triggers on your platform accept a payload before they know who sent it.
The runner is on the attack surface. It has been for a long time. Cordyceps is only the latest reminder to act like it.
Source: The New Stack (thenewstack.io)