A GitHub issue is now a credential-stealing primitive
Three coding agents, three unrelated exploits, one shared mistake: the code that checked the action was not the code that performed it.
The attacker in this story has a GitHub account, no write access to anything, and one move: open an issue. That is the whole budget. It works because somewhere in the repository's automation an agent will read that issue and treat it as instruction.
A download counter as the exfiltration channel
The Claude Code advisory describes something better than a stolen key. huggingface.co was pre-approved as a bare hostname for WebFetch, so fetching an attacker-controlled file under it raised no prompt. No allowlist was broken; the domain really was on the list.
Then the channel: Hugging Face counts downloads server-side, and the owner of a repository can watch that counter move. So the payload sends nothing anywhere. It reads a secret and encodes it by choosing which files to request.
Trust that shipped inside the repository
The Gemini CLI finding is a straight 10.0, and the reason is structural rather than clever. In headless mode the tool trusted workspace folders automatically, and under --yolo it ignored the user's own tool allowlist. The configuration meant to constrain the agent lived inside the thing the agent was pointed at, so a pull request could bring its own permissions.
Poisoning the file the next pass will obey
The third chain needs no CVE because it needs no bug. It is a workflow that runs the agent twice and lets the first run write a file the second run reads as authority.
1. attacker content lands in a GitHub issue 2. pass one writes it into AGENTS.md 3. pass one returns invalid JSON on purpose, so the job retries 4. pass two loads AGENTS.md as authoritative instructions 5. attacker holds standing control of pass two
Step three is the craft. Failing deliberately is what causes the second pass to exist, so the retry logic is not being broken, it is the delivery mechanism.
One from outside the AI world
The same window produced an origin validation error in Windows NAT. Before anyone panics, read the vector: AV:A means adjacent network rather than internet, and AC:H means high complexity. A strong finding for somebody already on your segment, which is a narrower threat model than the score alone suggests.
The pattern worth keeping
CSA names the root cause well: validation that inspects a command as a plain string diverges from the shell, interpreter or parser that executes it. Every finding above lives in that gap, and it is the same claim we make about MCP servers from the other side. If an agent reads tool descriptions and acts on them, the description field is not documentation, it is input.
- Patch the three tools to the versions in the ledger below.
- Stop handing long-lived secrets to jobs that read untrusted repository content. Scope tokens per job, keep them short lived.
- Never let one agent pass write the instruction file another pass reads. Instruction files belong to the repository owner, not to the run.
- Audit allowlists for what they permit, not who they name. A trusted host serving attacker-controlled paths with observable side effects is an exfiltration channel with a good reputation.
- Claude Code: GHSA-fg94-h982-f3mm / CVE-2026-54316, npm @anthropic-ai/claude-code, vulnerable >= 0.2.54 and < 2.1.163, patched in 2.1.163. Moderate, CVSS 6.0, published 13 June 2026.
- Gemini CLI: GHSA-wpqr-6v78-jr5g, @google/gemini-cli below 0.39.1 plus 0.40.0-preview.2, and run-gemini-cli below 0.1.22. Patched in 0.39.1, 0.40.0-preview.3 and 0.1.22. Critical, CVSS 10.0, AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H, published 24 April 2026.
- Windows NAT: CVE-2026-56181, origin validation error allowing spoofing over an adjacent network. CVSS 3.1 base 8.3, High, AV:A/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H. Fixed builds start at 10.0.26100.8875 on Windows 11 24H2. Published 14 July 2026.
- The Codex chain carries no CVE. Per the Cloud Security Alliance note, OpenAI split the two agent passes into separate jobs.
- The CSA note cites CVE-2026-12537 for the Gemini CLI issue, but GHSA-wpqr-6v78-jr5g states no CVE is assigned. We could not reconcile the two, so every Gemini figure here comes from the advisory.
- We reproduced none of this. It rests on the published advisories plus the CSA write-up, and we hold no independent proof of exploitability.
- Whether the Codex pattern is closed in general is unknown. Splitting the passes addresses the reported chain, not the class.
- Quoted percentages about how many MCP servers are vulnerable circulate through vendor blogs with no published methodology, so we do not repeat them.
- NatJack reportedly also covers a Linux netfilter issue. We did not verify that identifier, so it is not cited.

