Cloud & DevOpsSecurity

Cordyceps: GitHub Actions CI/CD Hijack via Pull Request

On June 23, 2026, Novee Security published research disclosing “Cordyceps” — a systemic class of vulnerabilities hiding inside the GitHub Actions CI/CD pipelines of Microsoft, Google, Apache, Cloudflare, and the Python Software Foundation. The attack requires no org membership, no elevated access, no special skills. A free GitHub account and a pull request are sufficient to steal secrets, hijack build pipelines, and inject code into software releases. In a scan of 30,000 high-impact repositories, Novee found 300+ confirmed fully exploitable. The affected organizations have patched their repos. The underlying pattern, however, remains widespread.

How the Cordyceps CI/CD Attack Works

The vulnerability is architectural, not a bug in anyone’s code. GitHub Actions has three event triggers — pull_request_target, workflow_run, and issue_comment — that execute workflows in the base repository’s privileged context, even when triggered by a fork PR from a complete stranger. Most developers assume these behave like the standard pull_request trigger. They don’t. The standard trigger runs with read-only access and no secrets. These three run with write permissions and full access to repository credentials.

What Novee named Cordyceps is the multi-step exploit that flows from this: an attacker opens a PR or leaves a comment, attacker-controlled text (PR title, branch name, comment body) gets interpolated into a shell command, that command runs in a privileged context, and the attacker walks out with secrets, cloud credentials, or the ability to push to main. Researcher Elad Meged stated it plainly in Novee’s Cordyceps research: “No org membership or special privileges; a free account is enough to forge approvals, push code, or steal credentials.”

The confirmed attack scenarios illustrate the severity. At Microsoft’s Azure Sentinel repository, a PR comment enabled theft of non-expiring GitHub App keys. At Google’s AI Agent Development Kit, a single PR could grant the highest-level Google Cloud owner role. Apache Doris had two independent zero-click paths to credential theft. Cloudflare’s Workers SDK allowed arbitrary command execution via crafted branch names. Python’s Black formatter was vulnerable to bot token theft enabling main-branch code injection.

AI Tools Are Making This Worse, Not Better

Novee’s research flags something more troubling than the vulnerability itself: AI coding agents are scaling the problem. Tools like GitHub Copilot, Cursor, and Claude Code generate GitHub Actions YAML configurations quickly by reproducing common patterns. Those common patterns include the dangerous pull_request_target configurations that make Cordyceps possible. The result is a self-replicating vulnerability machine — developers ask AI tools to scaffold CI/CD pipelines, the tools output functional-but-insecure configurations, and the attack surface grows at LLM speed.

This isn’t speculation. Microsoft’s own Security Blog addressed this dynamic in June, publishing guidance on securing CI/CD in an agentic world. Moreover, GitHub’s 2026 Actions Security Roadmap directly responds with planned changes including execution policies that can prohibit pull_request_target events at the organization level, scoped secrets, and workflow dependency locking. The platform is playing catch-up with a pattern that has spread further and faster than manual auditing can address.

Related: GitHub Actions Checkout v7: Migrate Before July 16 — the checkout v7 update directly blocks the most dangerous pull_request_target patterns Cordyceps exploits.

The Vulnerable Pattern vs. the Fix

The most common Cordyceps configuration is deceptively simple:

# VULNERABLE — grants attacker code access to repo secrets
on: pull_request_target
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}  # attacker's code
      - run: npm install && npm test                       # runs with repo secrets

The fix is a mindset shift as much as a code change: separate untrusted build work from privileged operations. Use pull_request (not pull_request_target) for build and test steps. If you genuinely need to comment on PRs or publish artifacts after tests, use a separate privileged workflow_run job that reads artifact data — never executes it. Keep pull_request_target for the narrow set of operations it was designed for: actions requiring write access that don’t touch untrusted code.

# SAFE — untrusted build runs without secrets or write access
on: pull_request
permissions:
  contents: read
jobs:
  test:
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

What to Do Right Now

The 300+ confirmed repos are patched. Yours may not be. Three concrete steps to take today:

Audit your workflows. Search your .github/workflows/ directory for pull_request_target and workflow_run triggers. For each one, verify whether untrusted input — PR title, branch name, comment text — flows into a shell command or gets executed. Tools like StepSecurity’s Harden-Runner and open-source scanners gato-x and poutine can check repositories at scale.

Set least-privilege defaults. Add permissions: contents: read at the top of every workflow file, then grant write access only to the specific jobs that need it. This limits blast radius even when a configuration mistake exists. Additionally, enable “Require approval for all outside collaborators” in repository settings to stop workflow auto-execution from untrusted forks — a simple gate that blocks the most common Cordyceps attack path.

Key Takeaways

  • Cordyceps is a class of CI/CD vulnerabilities, not a single CVE. It exploits trust boundary violations in GitHub Actions workflows, enabling full pipeline hijacking from a free account.
  • Microsoft, Google, Apache, Cloudflare, and the Python Software Foundation all had confirmed exploitable repositories. All are patched. The pattern remains common across the ecosystem.
  • AI coding agents are accelerating the spread by reproducing insecure CI/CD configurations at scale. Functional YAML is not the same as secure YAML.
  • Treat .github/workflows/ as security-critical code, not deployment configuration. Audit pull_request_target usage, apply least-privilege permissions, and separate untrusted build steps from privileged operations.
ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *