A maximum-severity flaw (GHSA-wpqr-6v78-jr5g / CVE-2026-12537) let an unprivileged outsider execute commands on CI runners using Gemini CLI in headless mode — by planting configuration or a prompt the agent trusted, before any sandbox or model was involved.
A maximum-severity flaw let an unprivileged outsider execute commands on the CI runner wherever Gemini CLI ran in headless mode — by planting content the agent trusted. Tap any node to open its deep-dive.
In headless mode the agent auto-trusted the workspace and loaded a planted .gemini/ config, executing on the host before the sandbox even started. No prompt injection, no model decision.
A hidden prompt in a public GitHub issue drove the auto-triage agent, which in --yolo ignored its tool allowlist and ran shell commands — stealing secrets and pivoting to repository write access.
Advisory GHSA-wpqr-6v78-jr5g · CVE-2026-12537 · CVSS 10.0 · found by Novee Security and Pillar Security. Eight tabs, one self-contained page.
In CI, Gemini CLI ran in headless mode and automatically trusted whatever workspace it was handed — loading configuration and environment variables an attacker could plant.
Gemini CLI loads configuration (.gemini/settings.json, environment variables) from the folder it runs in. Whether it asks first depends entirely on the mode. Switch modes and watch whether an attacker-planted config is silently accepted.
The default that broke. In an interactive terminal Gemini CLI prompts before trusting a folder. In headless mode — the way it runs inside CI/CD — earlier versions automatically trusted any workspace folder, loading its .gemini/ configuration and environment variables with no consent, no review, and no sandbox. An attacker who could place files in that workspace (a pull request from a fork, a checked-out untrusted branch) controlled the agent configuration.
Mapped to CWE-20 (improper input validation) and CWE-200 (exposure of sensitive information). The patch (@google/gemini-cli 0.39.1) removes the automatic trust: headless runs over untrusted directories now require the folder-trust mechanism to be configured deliberately.
The mode that lets an agent run unattended also skipped the tool allowlist, auto-approving every call — including a shell.
An allowlist in ~/.gemini/settings.json is supposed to limit which tools the agent may call. The second root cause: --yolo mode (auto-approve everything) ignored that allowlist entirely. Switch modes and watch whether an injected run_shell_command is allowed through.
Auto-approve, unbounded. --yolo exists so an agent can run unattended in CI without a human approving each tool call. Pre-patch it skipped the fine-grained allowlist, so every tool call — including run_shell_command — was approved automatically. Combined with an agent that triages untrusted input (a public issue, a PR), an injected instruction could invoke arbitrary shell commands. This is OWASP LLM07 (insecure plugin/tool design) and LLM08 (excessive agency).
In 0.39.1 the policy engine evaluates the allowlist even under --yolo. A caveat worth auditing: an allowlist is only as good as its entries — permitting a file reader like run_shell_command(cat) still lets /proc and .git/config leak secrets.
The most counter-intuitive part: the malicious configuration executed on the host in the container launcher, before the agent sandbox initialized. No model was ever involved.
Agentic tools run model-driven actions inside a sandbox. The sharpest part of this flaw: the malicious config executed in the container launcher, before the sandbox initialized. Switch from the mental model to what actually happened.
When data becomes code. A config file is “passive data” right up until something loads it. Here the launcher read attacker-controlled environment variables from the trusted workspace and an OS command injection (CWE-78) in that launcher executed on the host — outside and ahead of the sandbox meant to contain the agent. The sandbox was never the boundary the attacker had to beat.
This is why the finding is “infrastructure-level”, not an AI-safety issue: no model reasoned about anything. It also breaks the classic data/code separation that decades of security tooling assume — an agent turns configuration, hooks and templates into instructions the moment it interprets them.
Each weakness feeds the next: untrusted input, a trusting agent, a shell, stolen secrets, and finally write access to a widely depended-on repository.
Pillar Security demonstrated the full chain on the real gemini-cli repository. Each stage feeds the next. Switch the pipeline configuration and watch how far the compromise propagates — teal stages are blocked, amber stages are reached.
From comment to commit access. An attacker opens a public issue containing a hidden prompt. The auto-triage workflow runs Gemini CLI, which (in --yolo) executes a shell command, reads the build environment, and exfiltrates secrets to an attacker server. Those credentials are escalated — in the proof of concept, by triggering another workflow — until the attacker holds contents: write and can alter the repository itself. On a repository with 100k+ GitHub stars, that is a textbook supply-chain compromise (LLM05).
Why a CI runner is such a prize: it typically holds the workflow’s full credential set — repository secrets, cloud provider tokens, deployment keys — so host code execution there reaches far beyond the runner.
This flaw lived in the interplay of agent, code, pipeline, cloud, and host — precisely the seam that single-layer security tools do not inspect.
Each traditional tool inspects one layer in isolation. This flaw lived in the interplay between an agent, a CI pipeline, and the host. Tap a column to highlight which tools cover that layer — then look at the last column.
| Tool | Model behavior | App code | CI/CD pipeline | Cloud perms | The interplay |
|---|---|---|---|---|---|
| Static analysis (SAST) | ✗ | ✓ | ✗ | ✗ | ✗ |
| Dependency / CVE scanners | ✗ | ~ | ✗ | ✗ | ✗ |
| AI safety / red-team review | ✓ | ✗ | ✗ | ✗ | ✗ |
| Traditional pentest | ✗ | ~ | ~ | ~ | ✗ |
| Agent-aware adversarial test | ✓ | ✓ | ✓ | ✓ | ✓ |
Tap a column header to highlight coverage. The rightmost column — how the layers behave together under attack — is empty for every traditional tool.
The gap between checklists. SAST flags a missing check in source; dependency scanners catch a known CVE in a package; AI-safety reviews probe a model in isolation; pentests poke at infrastructure. None of them watches how an agent, the code it touches, the pipeline it runs in, and the host behave together when an external attacker is in the loop — which is exactly where this lived: attacker content silently accepted as configuration and executed before any model or sandbox.
The takeaway for a governance program: an AI coding agent in CI is a new trust boundary, and validating it needs a combined view of agent + application + pipeline + cloud + host, not four separate scans.
Upgrading closes both root causes; disciplined workflow design keeps an agent that processes untrusted input from becoming a supply-chain entry point.
Upgrading closes both root causes; the workflow around the agent is what keeps it closed. Step up the defenses and watch the three controls turn.
Do this. Upgrade @google/gemini-cli to ≥ 0.39.1 (or ≥ 0.40.0-preview.3) and google-github-actions/run-gemini-cli to ≥ 0.1.22. Then harden the pipeline: prefer pull_request_target with an explicit checkout of the base branch so untrusted fork code never runs; scope or disable --yolo; keep tool allowlists tight (knowing a permissive file reader still leaks); grant the workflow least-privilege tokens; and audit Actions logs for anomalous tool executions.
For a vendor or internal review: did any pipeline run a vulnerable Gemini CLI on external pull requests in the last ~30 days (if so, rotate the reachable secrets)? Is folder trust configured deliberately rather than assumed? Is --yolo used anywhere it processes untrusted input? Is the agent’s token least-privilege? Advisory: GHSA-wpqr-6v78-jr5g / CVE-2026-12537.
The maximum-severity finding did not appear from nowhere: an earlier prompt-injection bug, then a deeper architectural finding by two teams, a fast patch, and a formal CVE two months later.
google/draco repository, where Gemini CLI ran in --yolo and auto-trusted the workspace.gemini-cli repository itself — from a public issue to repository write access.GHSA-wpqr-6v78-jr5g (CVSS 10.0) and ships fixes: @google/gemini-cli 0.39.1 and google-github-actions/run-gemini-cli 0.1.22. Novee Security is independently credited.CVE-2026-12537 (CVSS v4 10.0), the formal identifier alongside the original GHSA advisory.Two findings, one advisory. The flaw was reported independently by Dan Lisichkin (Pillar Security) and Elad Meged (Novee Security), both through Google’s Vulnerability Rewards Program. Pillar approached it from prompt injection and excessive agency; Novee from the infrastructure side, where attacker content is silently trusted as configuration. They describe the same CVSS 10 surface from two angles.
It fits a wider pattern: an early prompt-injection finding on a freshly released agentic tool, followed months later by a deeper, higher-severity architectural finding as researchers map the full trust model. The same April 2026 news cycle carried related code-execution flaws in the Cursor IDE (for example CVE-2026-26268) — a different mechanism, the same theme of an agent treating repository content as instructions.