Cybersecurity · AI Agent Security
Black Hat 2026: A GitHub Issue With No Privileges Compromised Claude Code, Gemini CLI, and Codex
Researchers at Black Hat USA 2026 showed how an untrusted GitHub issue reached CI runner secrets in Claude Code, Gemini CLI, and OpenAI Codex. Gemini CLI's flaw scored a perfect 10.0 CVSS. Here's what happened and how to check your own pipelines.
Prathviraj Singh
5 min read
Sponsored
An account with no write access to a repository, nothing more than the ability to open an issue, was enough to get code running on a CI host behind three of the biggest names in AI coding tools. That’s the headline from Novee Security’s Black Hat USA 2026 talk on August 5, and the detail that should worry anyone running an AI coding agent in a pipeline is how ordinary the setup was: each vendor’s own default configuration, tested on each vendor’s own public repository. Nothing about this was a contrived lab scenario.
Three agents, three different ways in
Researcher Elad Meged’s team ran the same basic question against Claude Code, Gemini CLI, and OpenAI Codex: if an attacker can only reach a repo through an issue or a pull request, how far can that get them once an agent starts processing it? The answers differed by vendor, but the starting privilege level was identical across all three: zero.
Gemini CLI’s flaw is the standout, and not in a good way. CVE-2026-12537 is an OS command injection carrying a perfect 10.0 on CVSS 4.0. Gemini CLI, running headless in a CI job that reviews pull requests, automatically trusted any workspace folder and loaded configuration files inside a .gemini/ directory, including .env files, without requiring explicit authorization first. A malicious .gemini/.env file committed as part of an untrusted PR gets read as legitimate configuration and executes on the host, before the sandbox has fully engaged. That’s remote code execution from an unprivileged submission, on a headless platform, before any containment kicks in. It affects Gemini CLI before 0.39.1 and the run-gemini-cli GitHub Action before 0.1.22, both of which now carry the fix.
Claude Code’s flaw is quieter but just as real. CVE-2026-54316 exploited a domain allow-list decision: huggingface.co was pre-approved as a bare hostname for the WebFetch tool, so any path on that domain, including an attacker-controlled model repository page, got fetched without a permission prompt. Novee turned that into an exfiltration channel by encoding a stolen API key in Hugging Face’s public download counter, one character at a time, reading the count back through the same pre-trusted domain. Every Claude Code release from 0.2.54 through 2.1.163 was affected; 2.1.163 fixes it.
OpenAI Codex’s finding never got a CVE at all, because OpenAI’s position is that the sandbox behaved exactly as documented. The mechanism was still real: a first agent run gets manipulated into writing an AGENTS.md file, which Codex automatically reads as trusted project instructions on its next run. Even when a workflow explicitly checked and rejected the first run’s direct output, the influence persisted through the file it left behind, because the second run trusted AGENTS.md on sight. OpenAI restructured its own repository within three days of disclosure, splitting the two agent runs into separate jobs with separate checkouts and read-only environments, which tells you the finding was taken seriously even without a formal advisory.
The common thread is trust boundaries, not bugs
None of these three are classic memory-safety or injection bugs in the traditional sense. Each one is a case of an agent trusting something it shouldn’t have: a config file inside an untrusted workspace, a hostname on an allow-list, a project-instructions file written by an earlier, untrusted run. That’s a meaningfully different category of problem than a missing input sanitizer, and it’s one that gets harder to catch with standard application security tooling, because the “input” here is a natural-language instruction or a filename convention, not a request parameter a scanner recognizes.
It’s also why patching alone doesn’t fully close the gap. Updating Gemini CLI and Claude Code fixes the two disclosed CVEs, but the underlying pattern, an agent extending implicit trust to something an untrusted party can influence, is exactly the kind of risk worth walking through the same way you’d review a database schema for the failure mode that only shows up in production: decide what your agent trusts by default, and check whether an attacker with the access level you actually grant to outside contributors could reach it.
What to actually check this week
If any of these three tools run in a CI or CD pipeline that processes external contributions, issues, or pull requests, three things are worth verifying directly rather than assuming the vendor’s default is safe:
| Check | Why it matters |
|---|---|
Gemini CLI version >= 0.39.1, run-gemini-cli >= 0.1.22 | Below this, an untrusted .gemini/.env file gets RCE on a headless host |
| Claude Code version >= 2.1.163 | Below this, any pre-approved domain in WebFetch can become an exfiltration channel |
| Whether a later agent run reads any file an earlier, untrusted run could have written | This is the Codex pattern, and it has no CVE to alert you, so it needs a manual look |
Beyond the version checks, the more durable fix is architectural: never let an agent run against untrusted repository content with the same credentials and file trust it would have on a run you initiated yourself. Separate jobs, separate checkouts, and a human or automated review gate between an untrusted run and anything that consumes its output are the same isolation principles that applied to build systems before AI agents existed. They didn’t stop applying just because the thing running in CI now writes its own commands.
The pattern across all three disclosures is the same lesson in three different costumes: an agent that can act inside your CI environment needs the same skepticism toward untrusted input that you’d apply to a stranger’s pull request, because functionally, that’s exactly what it’s processing.
Frequently asked questions
- What did Novee Security find at Black Hat USA 2026?
- Novee tested Claude Code, Gemini CLI, and OpenAI Codex running in each vendor's default CI/CD configuration, on the vendors' own public repositories. In each case, an attacker with no write access to the repository, just the ability to open a GitHub issue or pull request, could get code executed on the CI runner or manipulate a later agent run through prompt injection.
- Is CVE-2026-12537 actually as bad as a CVSS 10.0 suggests?
- For the affected setup, yes. It's an OS command injection reachable through a crafted .gemini/.env file, and Gemini CLI running in a headless CI job would load that file as configuration without requiring explicit authorization first, even when reviewing an untrusted pull request. That gives an unprivileged attacker code execution on the host before Gemini CLI's sandbox has fully engaged. It's fixed in Gemini CLI 0.39.1 and run-gemini-cli 0.1.22.
- How did the Claude Code exfiltration attack actually work?
- Claude Code's WebFetch tool auto-approved any path on huggingface.co as a pre-trusted domain, without a permission prompt, because the bare hostname had been allow-listed. An attacker could point that trust at an attacker-controlled model repository page and use Hugging Face's public download counter as a side channel, encoding a stolen API key one character at a time in the number of times a crafted file got fetched. It's fixed in Claude Code 2.1.163; every release from 0.2.54 up was affected.
- Why didn't OpenAI Codex get a CVE?
- Novee's Codex finding relied on a two-stage workflow: a first agent run gets manipulated into writing an AGENTS.md file, which Codex treats as trusted project instructions on its next run, even though the workflow's explicit check rejected the first run's direct output. OpenAI's position is that the sandbox behaved exactly as documented, so no CVE was issued, but OpenAI did restructure its own repository within three days, splitting the two agent runs into separate jobs with separate checkouts and read-only environments.
- What should a team running AI coding agents in CI do about this?
- Update Gemini CLI to 0.39.1+ and Claude Code to 2.1.163+ immediately if either is in your pipeline. Beyond patching, audit which domains your agent's fetch tool trusts by default, never let a first agent run's output become a second run's trusted instructions without an explicit human or automated review step in between, and treat any CI job that lets an agent process untrusted issue or PR content as needing the same isolation you'd give a build step that runs someone else's code, because that's what it is.
Sources
Sponsored
More from this category
More from Cybersecurity
R.01 CVE-2026-59309 and 59310: VMware vCenter Bugs Attackers Hit in Five Days
R.02 The Ceva Logistics Breach Shows Why Your Vendor's Vendor Is Your Problem
R.03 CVE-2026-62878: The Wormable Windows DNS Server Bug You Need to Patch Now
Sponsored
Discussion
Join the conversation.
Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.
Sponsored