Safe AI Academy · interactive deep-dive

Gemini CLI CVSS 10 — when a pull request runs code in your CI

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.

The map

One pull request, code running in your CI

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.

Path A · no model

Trusted configuration

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.

Path B · excessive agency

Trusted instructions

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.

01

The same chain, end to end

Untrusted input the agent trusts, run inside a privileged pipeline.
Untrusted input a PR or public issue
An outsider plants a file or a prompt that the pipeline will process.
Open: how trust is granted ›
A trusting agent in CI headless · --yolo
⚠ trusts it
Gemini CLI accepts it as configuration or instructions and runs a tool.
Open: the attack chain ›
Host & supply chain secrets → write access
⚠ RCE
Code runs with the runner credentials; secrets are stolen and the repository is taken over.
Open: the fix & hardening ›
The two root causestwo trust defaults that compound into CVSS 10
Headless workspace trust
Why CI mode auto-trusted attacker-plantable config.
--yolo ignores the allowlist
Why auto-approve mode ran any shell command.
How it executeswhere the code runs and how far it reaches
Pre-sandbox execution
How code ran on the host before the sandbox existed.
The supply-chain chain
From a public issue to full repository takeover.
Defense & governancewhy scanners missed it, how to close it, and how it unfolded
Why scanners missed it
The interplay no single traditional tool can see.
The fix & hardening
Patch versions plus the workflow changes that matter.
Disclosure timeline
From a 2025 precursor to the June 2026 CVE assignment.

Advisory GHSA-wpqr-6v78-jr5g · CVE-2026-12537 · CVSS 10.0 · found by Novee Security and Pillar Security. Eight tabs, one self-contained page.

Root cause 1 · trust

Headless workspace trust — the agent trusted a folder an outsider could fill

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.

Who decides a folder is trusted?

interactive · workspace trust

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.

Root cause 2 · agency

--yolo ignored the allowlist — auto-approve with no limits

The mode that lets an agent run unattended also skipped the tool allowlist, auto-approving every call — including a shell.

Does the allowlist still apply?

interactive · --yolo & tool policy

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.

Execution · the boundary

Pre-sandbox execution — code ran before the sandbox existed

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.

The sandbox you thought was protecting you

interactive · where the code runs

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.

Impact · the full chain

The attack chain — from a public issue to repository takeover

Each weakness feeds the next: untrusted input, a trusting agent, a shell, stolen secrets, and finally write access to a widely depended-on repository.

How far does one public issue get?

interactive · the supply-chain chain

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.

Defense · the blind spot

Why traditional tooling missed it — the gap between the scans

This flaw lived in the interplay of agent, code, pipeline, cloud, and host — precisely the seam that single-layer security tools do not inspect.

What can actually see this bug?

interactive · tap a layer

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.

ToolModel behaviorApp codeCI/CD pipelineCloud permsThe 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.

Defense · close it

The fix and hardening — patch the defaults, then the pipeline

Upgrading closes both root causes; disciplined workflow design keeps an agent that processes untrusted input from becoming a supply-chain entry point.

Patch, then harden the workflow

interactive · layers of defense

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.

Context · how it unfolded

Disclosure timeline — from a 2025 precursor to a 2026 CVE

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.

Precursor — a prompt-injection flaw
Jun 27, 2025
Tracebit reports a prompt-injection issue two days after Gemini CLI’s public release. Google escalates it to Priority 1 / Severity 1 and patches it on July 25, 2025 — but the deeper trust model for headless deployments persists into CI scenarios.
Pillar reports the trust flaw
Apr 16, 2026
Pillar Security reports the issue against Google’s google/draco repository, where Gemini CLI ran in --yolo and auto-trusted the workspace.
Full chain demonstrated
Apr 20, 2026
Pillar demonstrates the complete attack end to end on the gemini-cli repository itself — from a public issue to repository write access.
Advisory and patch
Apr 24, 2026
Google publishes advisory 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 assigned
Jun 23, 2026
The flaw is registered in the National Vulnerability Database as 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.