# A GitHub issue could hijack Claude Code and Gemini CLI

> Novee showed one GitHub issue could reach secrets via Claude Code, Gemini CLI and Codex actions. Fixed versions, a corrected CVE mapping and a hardening checklist.

Canonical: https://www.nihardaily.com/posts/a-github-issue-could-hijack-claude-code-and-gemini-cli
Last updated: 2026-10-21

- Published: 2026-08-08
- Author: Nihar Ranjan Das
- Reading time: 8 min
- Categories: Software
- Tags: claude code, gemini cli, openai codex, github actions, prompt injection, ai agent security, developer security, black hat 2026

## Key takeaways

- Novee Security showed a GitHub issue could reach CI secrets through Claude Code Action, the Gemini CLI action and an OpenAI Codex workflow.
- CVE-2026-54316 is a Claude Code CLI bug fixed in 2.1.163; Gemini's CVSS 10.0 advisory is fixed in Gemini CLI 0.39.1 and run-gemini-cli 0.1.22.
- Gemini's fix is a breaking change: headless runs now need explicit folder trust, so upgrading alone may change your workflow.
- Remove write permissions from jobs that read untrusted text, split privileged work into separate jobs, and treat files the workflow wrote as untrusted.

Yes, a GitHub issue could hijack Claude Code, Gemini CLI and OpenAI Codex when they ran in a GitHub Actions workflow, and all three vendors have shipped fixes. The practical answer is to upgrade the actions, strip write access from any job that reads text a stranger wrote, and audit your own workflows for the same shape. We have corrected one detail from our August post: CVE-2026-54316 belongs to the Claude Code CLI, not the GitHub Action.

## What changed since August

- **The CVE mapping was wrong.** CVE-2026-54316 is a Claude Code CLI bug, fixed in version 2.1.163, per the [GitLab advisory database](https://advisories.gitlab.com/npm/@anthropic-ai/claude-code/CVE-2026-54316/). It was published on June 17, before the Black Hat talk.
- **Fixed versions are public.** Gemini CLI 0.39.1 and run-gemini-cli 0.1.22 carry the fix for GHSA-wpqr-6v78-jr5g, according to the advisory mirrors we checked.
- **Gemini's remediation has two branches.** Upgrading is not the whole story. Headless runs now need explicit folder trust, and you must decide how to set it.
- **Scope.** Novee found the Gemini pattern in 114 repositories. Our August post attached a "100 repositories" figure to Codex, which its write-up does not support.

## What did the researchers break?

**Prompt injection** is hiding instructions inside content that a model reads, so the model follows the attacker instead of its operator. The new part is where the instructions landed. A **GitHub Actions runner** is the temporary virtual machine that executes a repository's automation, and it typically holds a repository token plus any API keys the workflow needs.

Novee Security's [write-up of the three chains](https://novee.security/blog/critical-flaws-in-anthropic-google-and-openais-coding-agents/) shows that an unprivileged GitHub issue was enough to reach those secrets on repositories owned by Anthropic, Google and OpenAI. The researchers presented at Black Hat USA on August 5 after disclosing to the vendors.

| Product | Identifier | What an issue could reach |
|---|---|---|
| Claude Code Action | Fixes via allowlist changes; CVE-2026-54316 covers the CLI | `GITHUB_TOKEN` and `ANTHROPIC_API_KEY` |
| Gemini CLI and run-gemini-cli | GHSA-wpqr-6v78-jr5g, CVSS 10.0 | The parent process environment, then a push to `main` |
| OpenAI Codex action | No CVE | A second agent pass that obeyed a planted file |

!Diagram of three attack chains from a GitHub issue through a validator bypass to workflow secrets for Claude Code Action, Gemini CLI and Codex

## How the Claude Code chain worked

The Claude Code Action defaults in tag mode, triggered by commenting `@claude` on an issue, allow `Edit`, `Read`, `Write` and several `git` commands. Bash approval used prefix matching. The chain had three rounds.

**Round one, code execution.** The injected instruction ran `git push --receive-pack='sh -c "..."'`. The validator stripped quoted content before checking the command, so it saw an empty flag value. Git then executed the quoted string. Anthropic's fix was a git push allowlist and removal of most Bash tools.

**Round two, file reads and a leak.** Commands such as `tac`, `rev` and `fold` were auto-approved as read-only but missing from the path check. A regex guarded `/proc/self/environ`, and writing the path as `rev /proc/self/enviro""n` slipped past it. With `display_report` on, tool output landed in the public step summary, so reversed secrets became readable. The fix turned that off and sanitized the output.

**Round three, exfiltration through a counter.** WebFetch had about 88 pre-approved domains, including bare `huggingface.co`. The attacker encoded secret characters into repository fetches and read the answer from public download counters. That is the bug behind CVE-2026-54316. The advisory rates it 9.1 on CVSS 3.1 and says it affects Claude Code from 0.2.54 up to, but not including, 2.1.163.

## Why the Gemini CLI bug scored a 10

**CVSS** is the industry severity scale, and 10.0 is the worst rating on every axis. Two mistakes stacked. A prefix match registered the whole shell tool, and the runtime never enforced the tool restriction. Then the environment cleanup only covered the child process, so the parent's `/proc/$PPID/environ` still held `GITHUB_TOKEN`.

Novee's chain read that token, dispatched a second workflow with `contents: write`, and pushed to `main` on the Gemini CLI repository, which has about 2 million monthly downstream installs. The vulnerable workflow ran on any GitHub user's issue, in yolo mode.

Google's fix is a breaking change to how headless environments treat folder trust. According to the advisory mirrors, headless runs used to trust the workspace folder automatically, so a crafted `.gemini/` directory in a pull request could inject environment variables. Now trust is explicit:

- **Trusted inputs only:** you can set `GEMINI_TRUST_WORKSPACE: 'true'` in the workflow.
- **Untrusted inputs:** harden the workflow along the run-gemini-cli guidance instead.

Pinned versions need attention. The action pulls the latest Gemini CLI by default, but if you set `gemini_cli_version`, move to 0.39.1 or later. The advisory sources disagree slightly on preview ranges, so read the primary advisory before you rely on a preview build.

## Why Codex has no CVE

The Codex issue was a design flaw rather than a memory or parser bug. The vulnerable `issue-deduplicator.yml` workflow ran two Codex passes in one job, sharing one checkout under the default `workspace-write` sandbox. The sandbox protected `.git`, `.agents` and `.codex`, but not `AGENTS.md`, which Codex loads as instructions.

Pass one could be steered into writing `AGENTS.md`, and the output then looked invalid, which triggered pass two. Pass two loaded the attacker's file as guidance. Nothing broke technically, so there was no CVE.

OpenAI split the passes into separate jobs with separate checkouts three days after the report. Later it removed the checkout, moved Codex steps into a read-only sandbox without sudo, and documented `AGENTS.md` as an untrusted input surface.

## What to change in your workflows

If an agent reads issues or pull requests in your repository, these changes carry most of the value.

1. **Upgrade first.** Claude Code to 2.1.163 or later, Gemini CLI to 0.39.1 or later, run-gemini-cli to 0.1.22 or later.
2. **Remove write permissions** from anything triggered by untrusted input. A job that only needs to comment does not need `contents: write`.
3. **Split privileged and unprivileged work** into separate jobs with separate checkouts.
4. **Treat every file the workflow wrote as untrusted.** That is the Codex lesson, and it applies to any multi-step agent.
5. **Stop allowing every user** on automation that reads issues. The Codex workflow used `allow-users: "*"`.

A minimal hardening sketch looks like this:

```yaml
permissions:
  contents: read
  issues: write        # comment only, no push

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false
      # agent step here, with no secrets beyond what triage needs
```

To find exposure fast, search your repositories for the actions and the risky settings:

```
grep -rnE "claude-code-action|run-gemini-cli|codex-action" .github/workflows
grep -rnE "allow-users|yolo|workspace-write|GEMINI_TRUST_WORKSPACE" .github/workflows
```

!Table-style chart of upgrade targets: Claude Code 2.1.163, Gemini CLI 0.39.1, run-gemini-cli 0.1.22, and a workflow redesign for the Codex pattern

## Which of your workflows is at risk?

Risk comes from two things meeting in one job: text an outsider wrote, and credentials the job can use. This table sorts common GitHub Actions triggers by that test. It reflects how GitHub treats each event, not anything specific to these three vendors.

| Trigger | Does outsider text reach the agent? | Secrets and write token available? | Risk |
|---|---|---|---|
| `issues` opened or commented by anyone | Yes | Yes, unless you remove them | High |
| `pull_request` from a fork | Yes | No secrets, read-only token by default | Lower |
| `pull_request_target` | Yes | Yes, runs with base repository secrets | High |
| `push` to your own branches | Only your commits | Yes | Low |
| `workflow_dispatch` by maintainers | Only what they type | Yes | Low |

The two high rows are the exact conditions in the research: an open trigger plus a job that holds a token with write access. A review bot that only posts comments should run with a token that cannot push, and it should never share a job with a step that can.

## Should you stop using agents on issues?

No, but price the privilege honestly. An agent that labels issues or drafts a reply is useful and cheap to contain, because it needs only `issues: write`. An agent that edits code and pushes needs a human gate before the push, such as a pull request that a maintainer reviews. The research shows that "the agent is allowed to run only a few commands" is not a control by itself, because every one of those allowlists failed at the matching step. Contain the credentials, and treat the allowlist as a second layer.

## Was it exploited in the wild?

We found no public report of exploitation. The chains came from researchers who disclosed to the vendors before the Black Hat presentation. The CLI CVE was published on June 17, so the vendors had weeks before the public write-up. That does not mean your own copy is safe, because forks and pinned workflow files do not update themselves.

## What the three bugs have in common

Every chain sat in a seam between two systems that each behaved correctly. A validator that stripped quotes. A registration check that matched prefixes. A workflow that trusted its own disk. Agents make those seams load-bearing, because an agent will carry an instruction across one without complaint.

The same shape appears in supply chain incidents, where an ordinary developer convenience becomes [credential theft](https://www.nihardaily.com/posts/how-the-keyv-npm-attack-reached-vs-code-and-claude-code). The risk is less about model behavior than about which privileges you hand to a job that reads text from strangers.

## The takeaway

The vendors have fixed their own repositories and shipped patched versions. Your job is to make sure your copies are patched, and that no workflow gives an agent write access while it reads untrusted text. The cheapest durable control is architectural: keep the part of the pipeline that reads issues separate from the part that holds secrets.


## FAQ

### Is Claude Code itself vulnerable, or just the GitHub action?

Both were involved. The Black Hat chain targeted Claude Code Action in its default tag mode. CVE-2026-54316 is a separate Claude Code CLI bug, where a pre-approved huggingface.co host let attackers leak data through WebFetch. It affects versions from 0.2.54 up to, but not including, 2.1.163. Upgrade the CLI and review your action settings.

### Which versions fix the Gemini CLI vulnerability?

Advisory GHSA-wpqr-6v78-jr5g, rated CVSS 10.0, is fixed in Gemini CLI 0.39.1 and run-gemini-cli 0.1.22. Headless runs now need explicit folder trust. For trusted inputs you can set GEMINI_TRUST_WORKSPACE to true. For untrusted inputs, harden the workflow instead. Check the primary advisory before pinning preview builds.

### Why does the Codex finding have no CVE?

It was a workflow design flaw, not a code bug. Two Codex passes shared one checkout, and pass one could write an AGENTS.md file that pass two loaded as instructions. OpenAI split the passes into separate jobs and moved Codex steps to read-only sandboxes, and documented AGENTS.md as an untrusted input surface.

### Was any of this exploited in the wild?

We found no public report of exploitation. The researchers disclosed to the vendors before presenting at Black Hat USA on August 5, 2026, and the Claude Code CLI CVE was published on June 17. Your own forks and pinned workflow files do not update themselves, so check them.

### How do I make my GitHub Actions agent workflows safer?

Remove write permissions from jobs triggered by untrusted input, split privileged and unprivileged work into separate jobs with separate checkouts, and avoid allowing every user to trigger the agent. Treat every file a workflow wrote as untrusted input, and upgrade Claude Code, Gemini CLI and run-gemini-cli to the fixed versions.

## Related

- [Nihar Ranjan Das](https://www.nihardaily.com/author/nihar-ranjan-das)
- [MCP vs UTCP: we timed both on the same 10 tools](https://www.nihardaily.com/posts/mcp-vs-utcp-we-timed-both-on-the-same-10-tools)
- [Nginx vs Caddy: we load-tested both reverse proxies](https://www.nihardaily.com/posts/nginx-vs-caddy-we-load-tested-both-reverse-proxies)
- [AI coding tools hid 15 GB on my Mac. unclog found it](https://www.nihardaily.com/posts/ai-coding-tools-hid-15-gb-on-my-mac-unclog-found-it)
