One Issue. Full Repository Access.
Anthropic’s Claude Code GitHub Action contained a vulnerability serious enough that exploiting it against Anthropic’s own repository could have poisoned every downstream project that pulled the action. The attack required no special access, no insider knowledge, and no complex toolchain — just a GitHub App anyone can register for free, and a carefully written issue body designed to mislead an AI model into doing the attacker’s work.
RyotaK of GMO Flatt Security reported the core issue to Anthropic in January. Anthropic patched it within four days and continued hardening the action through spring. The fixes landed in claude-code-action v1.0.94, with Anthropic rating the vulnerability at 7.8 under CVSS v4.0 and paying out a bug bounty.
What Claude Code Does — and Why Its Permissions Are Broad
Claude Code GitHub Action drops Claude into CI/CD pipelines where it handles routine repository maintenance: triaging issues, applying labels, reviewing pull requests, and executing slash commands. To do any of that work, it needs reach. By default, the action receives read and write access to a repository’s code, issues, pull requests, discussions, and workflow files. That’s a wide surface.
Because the permissions are so expansive, the action is supposed to gate itself carefully, limiting triggers to users who already hold write access to the repository. The assumption is that write-access holders are vetted. Everyone else should stay out.
That gate had a hole.
The Bot Name Bypass
The trigger check contained a logic error: it automatically allowed any GitHub actor whose username ended in [bot]. The reasoning behind the exception was that GitHub Apps — which carry names like renovate[bot] or dependabot[bot] — are tools administrators deliberately install and therefore implicitly trust. The problem is that the trust assumption doesn’t hold. Anyone can register a GitHub App, install it on a repository they control, and then use that App’s token to open an issue or pull request on any public repository. The action sees a name ending in [bot] and waves the content through, never checking who actually owns the App.
Tag mode had a secondary verification step that confirmed the actor was a genuine human user. Agent mode had no such check, which is what left it exploitable.
Indirect Prompt Injection as the Actual Weapon
Bypassing the bot check only gets an attacker’s content in front of Claude. What happens next depends on indirect prompt injection — the technique of embedding instructions inside content an AI model reads during a task, causing the model to execute those instructions instead of completing its original assignment.
RyotaK constructed an issue body that mimicked the appearance of an error message. He iterated on the prompt wording until Claude would interpret the fabricated error as something requiring recovery, and the “recovery” steps happened to be the commands he had buried in the text. The immediate target was /proc/self/environ, the Linux file that stores a running process’s environment variables, which in a CI context includes secrets and credentials.
Claude Code has defenses against naive reads of that file. RyotaK bypassed them regardless and coaxed Claude into writing the environment variable values back into the issue itself — visible to the attacker, pulled from the workflow’s live environment.
What sits inside those environment variables is worth explaining precisely, because this is where the attack escalates from annoyance to supply-chain threat. GitHub Actions workflows use a credential pair to request OIDC tokens — signed tokens that cryptographically assert “this is workflow X running in repository Y.” Claude Code takes that OIDC token and exchanges it with Anthropic’s backend for a Claude GitHub App installation token carrying write access. Steal the OIDC credentials before they expire, replay the exchange, and the attacker holds a write token for the target repository’s code, issues, and workflows — obtained without ever authenticating as a legitimate user.
Point that capability at the claude-code-action repository itself, and the attack becomes a supply chain compromise. Any project pulling the action after a malicious commit would inherit whatever payload was pushed.
A Second Route That Skipped the Bot Trick
RyotaK documented a softer attack path that didn’t require the bot account at all.
Anthropic’s own example issue-triage workflow shipped with allowed_non_write_users: "*" — a setting that permits anyone to trigger the action regardless of repository permissions. Anthropic’s documentation already flagged this setting as risky, but the example workflow shipped with it enabled. Many repositories copied that example configuration directly and inherited the exposure along with it.
The example workflow also had Claude posting task summaries to the workflow run’s publicly visible summary panel. That visibility makes the panel a ready-made exfiltration channel: any data Claude mentions in a summary becomes readable without authentication.
A third variant required no special account and no misconfigured trigger. If an attacker could edit an existing issue — a permission available to the original author even without write access — they could modify a trusted user’s issue after it triggered the workflow but before Claude read the content. Claude would process the edited, attacker-controlled text as trusted input, with no indication that the content had changed between trigger and execution.
What Actually Happened Before the Patch
This wasn’t purely theoretical exposure sitting in a lab report.
In February, a prompt-injected issue title against Cline’s claude-code-action triage workflow let attackers steal an npm publish token and push an unauthorized package version. The attack pattern was identical: an AI triager, broad permissions, and prompt injection through content the model was supposed to process innocuously. The Cline incident happened before RyotaK’s full report was published, but it demonstrated exactly the risk the vulnerability represented.
The mechanics here — an AI agent with write access consuming untrusted input — create a category of exposure that doesn’t map cleanly onto traditional vulnerability models. There’s no buffer overflow to patch or authentication endpoint to harden. The model’s ability to follow instructions embedded in arbitrary text is the feature; turning that feature against the workflow’s intended purpose is the attack.
What Needs to Happen Now
The immediate step is updating to claude-code-action v1.0.94 or later.
Beyond the version bump, any workflow that feeds untrusted input to Claude requires a permissions audit. If users without write access, or bot-named accounts, can trigger the workflow, the blast radius needs to be narrowed. Claude should receive only the Anthropic API key and GITHUB_TOKEN — nothing else from the environment. Any tools or permissions not strictly required for the task should be removed, specifically anything that could be used to read from sensitive paths or write output to visible locations.
The allowed_non_write_users: "*" setting should be treated as off by default. Repositories that copied Anthropic’s example workflow wholesale should check whether that setting is active and whether Claude’s task summaries are posting to the public summary panel.
The issue-editing timing window is harder to close architecturally, but limiting who can edit issues and adding integrity checks on content between trigger and execution reduces the exposure.
The Cline npm token theft in February cost real users a malicious package push. The GITHUB_TOKEN write credential Claude Code was exchanging for an installation token carries significantly more reach than a single publish token — and the claude-code-action repository had, at the time of discovery, no protection against having that reach turned back on itself.
CVSS 7.8. Fixed in v1.0.94. Bug bounty paid.