Skip to content

Anthropic patches Claude Code GitHub Action repo-takeover chain

GMO Flatt Security's RyotaK chained a checkWritePermissions bot bypass with prompt injection to hijack any public repo running claude-code-action. Fix shipped in v1.0.94.

Published 5 min read

Security researcher RyotaK of GMO Flatt Security published a writeup on June 4, 2026 detailing a chain that let an unauthenticated external attacker hijack any public repository running Anthropic's official claude-code-action GitHub Action by opening a single crafted issue. Anthropic rated the chain CVSS v4.0 7.8, paid a $4,800 bug bounty, and shipped the fix in claude-code-action v1.0.94. Microsoft's security team independently documented the same chain in a June 5 blog post reframing it as a case study in agentic CI/CD.

What the chain does

The exploit is three bugs stacked into one workflow trigger:

  1. checkWritePermissions bot bypass. RyotaK's writeup shows the function unconditionally trusted any actor whose login ends in [bot], regardless of the actual permission level returned by the GitHub API. GitHub Apps have implicit read access to every public repo and can open issues using only their installation token — meaning an attacker-controlled bot could trigger the workflow on any public repo it could file an issue against, even with zero write permission.
  2. Indirect prompt injection via the issue body. RyotaK then planted a faux error message in the issue body whose text instructed the model to "recover" by running shell commands. When the Action picked up the issue for triage, Claude followed the embedded instructions instead of the surrounding task — the classic indirect-prompt-injection pattern, applied to a triage workflow whose runner already has the repo's secrets in env.
  3. Example workflow misconfiguration. Anthropic's published example issue-triage workflow shipped with allowed_non_write_users: "*", meaning any GitHub user could trigger it. Combined with issues: write and a second workflow using id-token: write, the chain reaches full repository compromise plus OIDC token theft, with no authenticated attacker required at any step.

The kicker, in RyotaK's words, is that Anthropic's own claude-code-action repository used the same workflow. A successful chain there would have pushed malicious code into the Action itself, then downstream into every repo that pinned the tag — a classic supply-chain push.

Affected surface

  • All public repositories running claude-code-action prior to v1.0.94.
  • Private repositories running the action are not in scope for the unauthenticated-attacker variant of the chain because GitHub Apps cannot file issues without explicit access — but the prompt-injection primitive still applies to any issue text the Action consumes.
  • Forks of Anthropic's example workflows that copy-pasted allowed_non_write_users: "*" remain exposed even after upgrading claude-code-action, because the misconfiguration is in the consumer repository, not the upstream Action.

Exploitation status

The disclosure is coordinated. RyotaK reported the core bypass to Anthropic in January 2026 through HackerOne; Anthropic patched within four days and continued hardening through the spring before authorising public disclosure in June. No in-the-wild exploitation has been reported by Anthropic, RyotaK, or Microsoft. RyotaK published a working PoC against a test repo in his writeup but did not release a generic exploit kit.

The Microsoft Security blog post is the second independent technical writeup; The Hacker News and The Next Web provide the secondary coverage. There is no CVE assigned at the time of writing — Anthropic handled the disclosure through its own bounty pipeline and the version pin in the Action, not the CVE Numbering Authority track.

Action checklist

  1. Upgrade claude-code-action to v1.0.94 or later on every workflow that references it. Pin to a semver tag, not a floating @main or major-version ref — the bug bypassed the permission check in code, so a stale pin keeps the vulnerable function alive.
  2. Audit every workflow that consumes claude-code-action for allowed_non_write_users: "*" and remove the wildcard. If you need to allow non-write users, enumerate them — there is no benign reason to wildcard.
  3. Audit workflows that combine issues: write with id-token: write in the same job graph. The chain only reaches full repo compromise when both permissions land in the same execution context. Split them across separate workflows with explicit, narrow scopes.
  4. Rotate any secret reachable from a claude-code-action runner in a public repo touched by an issue from an external (non-collaborator) account between the workflow's introduction and the v1.0.94 upgrade. The exfiltration primitive in RyotaK's PoC reads process.env and writes the values back into the issue thread for the attacker to read.
  5. Review the repository's audit log for unexpected workflow runs triggered by actor: *[bot] against issues from external accounts. The bot-bypass primitive does not require human interaction; the log entry is the only public-facing footprint.
  6. Treat agentic CI/CD actions as Tier-0 supply-chain dependencies. The blast radius of an action that (a) reads attacker-influenced text and (b) has write access to the repo is identical to a credentialed insider — and the trust boundary is the runner, not the prompt.

Context

This is the second high-profile public dustup over agentic-CI security in two months — coverage on this site of the VS Code github.dev OAuth-token zero-day on June 2 covered the analogous failure mode in a browser-based IDE: text the user clicks influences code that runs with a token covering the user's whole account. The shape is the same. An agent that reads untrusted input runs in a trust context that the input authors do not deserve.

RyotaK's writeup frames the bug as a supply-chain risk, and that's the right frame. Every Action that an LLM-driven runner can install or invoke inherits the runner's identity. The June 5 Microsoft blog argues for treating permissions: and allowed_* lists as security policy under code review, with the same gate that a chmod 777 would draw in a non-agent codebase. The class of bug — actor.endsWith("[bot]") as an authentication primitive — is a permission-check anti-pattern older than GitHub Apps, but it has new teeth when the runner downstream is an autonomous agent with shell access. Until the principle of least authority is applied to the agent's output permissions as carefully as the network operators applied it to the runner's input scope, expect the same pattern to surface in every adjacent *-code-action, *-code-bot, and PR-triage agent that ships in 2026.

Related stories