Most teams adopted AI coding agents the same way: install it, point it at the repository, wire it into CI so it can respond to issues and pull requests. That last step is the one worth revisiting.

Novee Security presented findings at Black Hat USA on 5 August 2026 covering Claude Code, Gemini CLI and OpenAI Codex. Two produced CVEs. All three shared the same underlying shape, and it is a shape worth understanding rather than a list of bugs worth patching and forgetting.

The Gemini CLI flaw is the worse one

CVE-2026-12537 carries a CVSS 4.0 score of 10.0 — the top of the scale.

It is an OS command injection in the container launcher, reached through a crafted .gemini/.env file. The consequence is the part that matters: an unprivileged GitHub user can get code running on the host of a headless CI platform, before the sandbox starts.

Read that sequence again, because it inverts the assumption the whole design rests on. The sandbox is the control. It is what makes it acceptable to let an agent process input from strangers. If an attacker can execute on the host during the launcher's own startup, the sandbox never enters the picture — it is not bypassed so much as pre-empted.

The requirement to exploit it is a file in a repository. Not a maintainer's credentials, not a compromised dependency, not social engineering. A pull request from an account that opened yesterday.

Fixed in Gemini CLI 0.39.1 and run-gemini-cli 0.1.22.

The Claude Code flaw is the more inventive one

CVE-2026-54316 is rated 9.1 under CVSS v3.1. Anthropic scores it 6.0 under CVSS v4, which is a notable gap and worth stating plainly rather than picking whichever number suits the headline. Different versions of the scoring standard weigh exploitability and scope differently, and vendor self-scoring naturally sits at the lower end of a defensible range. Both numbers describe the same bug.

It affects every version from 0.2.54 through 2.1.163, and is fixed in 2.1.163.

The mechanism is where it gets interesting. The vulnerability allows API key exfiltration through Hugging Face download counters, one character at a time.

That deserves unpacking, because it is a genuinely elegant piece of work. Hugging Face publishes download counts for models. Those counters are public, they increment when a model is fetched, and they are observable by anyone. An attacker who can induce the agent to fetch a model chosen by the value of a character in a secret — one model per possible character — can then read the secret back by watching which counters moved.

No outbound connection to attacker infrastructure. No unusual domain in the egress logs. The traffic goes to Hugging Face, which is exactly where an AI coding agent is supposed to be talking. The data leaves through a side channel built out of a legitimate service's public metrics.

Detection controls that look for exfiltration to suspicious hosts see nothing at all.

What actually links the three

Novee's framing is the useful takeaway. Across the tools, the researchers found a recurring pattern:

one part marked a value safe, and a later part acted on that value with more authority

Two concrete instances:

Claude Code's command validator strips single-quoted text before running its security checks. So the validator inspects a version of the command with content removed, pronounces it safe, and the shell then executes the original — including a payload sitting inside a git flag value. The check and the execution disagreed about what the command was.

Gemini CLI parsed its tool allowlist only at registration time, with no runtime enforcement. The allowlist described what should be permitted. Nothing consulted it at the moment a tool actually ran. A control that exists in configuration and not in the execution path is documentation.

OpenAI Codex received no CVE. Its issue was that the first of two sequential passes could modify the instructions for the second — an agent editing its own downstream tasking. OpenAI addressed it through workflow separation and documentation changes rather than code, which is a reasonable response to a design property rather than a memory-safety error, though it does mean the fix depends on users reading the documentation.

Why this class will keep recurring

These are not careless bugs. They are the predictable result of a specific architecture: a system that takes untrusted natural-language input, decides what actions it implies, and then executes those actions with the permissions of whoever installed it.

Traditional security boundaries assume you can separate code from data. An agent's entire function is to erase that separation — it reads text and turns it into commands. Every validation layer is therefore trying to classify something whose meaning is not fixed until execution.

Add CI, and three things stack unfavourably:

  • CI hosts hold the credentials. Deploy keys, registry tokens, cloud roles, signing material. It is where the valuable secrets live because it is where the automation needs them.
  • CI runs on other people's input. Issues, comments and pull requests from anyone. That is the point of a public repository.
  • CI runs unattended. Nobody is watching the output at 3am.

An agent placed at that intersection is processing hostile input, with production credentials, with no human in the loop.

What to do

  • Update both tools now. Gemini CLI to 0.39.1 (and run-gemini-cli to 0.1.22), Claude Code to 2.1.163. The Claude Code window covers essentially the tool's entire release history, so "we installed it a while ago" means affected.
  • Audit every workflow an external user can trigger. The exposure is specifically in agents reacting to issues, comments and pull requests from outside the organisation. An agent that only runs on pushes to a protected branch is a different risk profile entirely.
  • Scope CI credentials to the job. If a workflow only needs to read a repository, it should not hold a deploy key. This is standard advice that agents make considerably more urgent, because the blast radius of an injection is exactly the set of credentials in scope.
  • Rotate what was reachable. For the Claude Code issue in particular, the exfiltration is silent by design. Absence of alerts is not evidence that nothing left.
  • Watch the egress you consider normal. The Hugging Face channel works because traffic to Hugging Face is unremarkable from a machine running an AI agent. Anything an agent is expected to talk to is a candidate carrier.

The thing worth internalising

The instinct after a disclosure like this is to patch and move on. The more useful reading is that the sandbox, the allowlist and the validator were all present in these products, and all three were defeated by ordering — a check performed against one version of a value while a different component acted on another.

That is not a bug you fix once. It is a property of gluing a probabilistic component into a system that expects deterministic boundaries, and it will keep surfacing in new tools until the boundary is enforced at the point of execution rather than asserted somewhere upstream.