Comment and Control Prompt Injection Across Claude Code, Gemini CLI and Copilot Agents - Credential Theft via GitHub Comments
Security researcher Aonan Guan, with Johns Hopkins researchers Zhengyu Liu and Gavin Zhong, disclosed a prompt injection technique called Comment and Control that hijacks AI coding agents wired into GitHub Actions through PR titles, issue bodies, and comments. The agent reads the attacker text as trusted context, runs the attacker's commands, and exfiltrates the results back through GitHub itself with no external server. The Anthropic finding was rated CVSS 9.4 Critical; Google and GitHub each paid bounties.
What happened
Comment and Control runs its entire loop inside GitHub. An attacker plants instructions in a comment, PR title, or issue body; the AI coding agent wired into a workflow reads that text as trusted context, runs the attacker's commands, and returns the results through a PR comment, an issue comment, or a git commit. Because the workflows auto-trigger on the pull_request, issues, and issue_comment events, opening a PR or filing an issue activated the agent without any victim interaction.
Against the Claude Code Security Review action, a malicious PR title broke the prompt context and made Claude run whoami, ps auxeww, and env, then return the credential dump packaged as a JSON security finding - the agent's own output channel became the exfiltration path. The flaw reported to Anthropic was rated CVSS 9.4 Critical.
The Gemini CLI Action (the run-gemini-cli action) was tricked by a fake Trusted Content Section in the attacker text into posting the GEMINI_API_KEY as a public comment. The GitHub Copilot Agent payload was hidden inside an HTML comment - invisible in rendered Markdown but still read by the agent. The root cause across all three is the same: untrusted text from a public surface was acted on as if a maintainer had typed it.
Why this is an agentic-endpoint risk
The attack surface here is not a vulnerable dependency or an exposed server - it is what a coding agent does on the runner when it treats a PR title or comment as part of its instructions. A comment is data, not a command, but the Claude Code, Gemini CLI, and Copilot agents each acted on attacker-supplied text while reviewing a pull request or answering an issue. Opening a PR was enough to make the agent run commands and hand back a secret.
This exposure is hard to see from the controls you already run, because it lives in the AI artifact layer. The agent process looks legitimate to EDR; the model API call looks like ordinary agent traffic to the network; and DLP sees nothing at rest because the secret leaves through a GitHub comment or commit, not a file. AI agents and CLIs are part of the eight AI artifact types Anomity tracks per endpoint, adopted bottom-up the same way AI coding agents and CLIs became the new shadow IT. The question is which runners host the Claude Code, Gemini CLI, or Copilot surfaces, and what tool calls those agents ran while processing a comment.
How Anomity surfaces and governs it
Provider-side hardening helps, but the durable control is to treat every PR title, issue body, and comment as untrusted input and govern what an agent may do when it acts on that input - which Anomity does in three steps.
First, inventory. Anomity inventories AI agents and CLIs on every managed endpoint and runner as part of the eight AI artifact types it tracks, then classifies them, capturing which surfaces are present - the Claude Code Security Review action, the Gemini CLI Action, or the GitHub Copilot Agent - so you can find every place a public comment reaches an agent. Anomity collects metadata only, and secrets such as the GEMINI_API_KEY are redacted on the endpoint, so the targeted credential is never centralized.
Second, decide at the hook. On agents that expose a hook - for example, the Claude Code PreToolUse event - Anomity evaluates each tool call against your policy and returns allow, deny, or log before the call runs. The env, whoami, and curl style calls these injections attempt can be denied at the boundary, which is what runtime governance provides while a fix is still rolling out - the same untrusted-input-crosses-a-trust-boundary class seen in the sibling Claude Code project-file RCE and token exfiltration and OpenAI Codex branch-name command injection advisories.
Third, keep the record. Anomity logs the tool calls an agent makes, so the commands a comment-driven payload triggers are recorded against a queryable 90-day audit trail, and decisions route to SIEM, Slack, email, or Jira. When a disclosure like Comment and Control lands, you can answer which runners host the affected agents, which PR or issue events spawned env or whoami calls, and whether a secret was read. Anomity complements your Network, EDR, DLP, and GRC tooling; it covers the artifact layer those tools never see.
You can't govern what you can't see.The Anomity principle
What to check across your fleet
- Inventory every runner that hosts an AI coding agent wired into GitHub Actions - the Claude Code Security Review action, the Gemini CLI Action (run-gemini-cli), and the GitHub Copilot Agent - and confirm each is hardened.
- Audit workflows that auto-trigger on the pull_request, issues, and issue_comment events, since opening a PR or filing an issue activated these agents with no victim interaction.
- Treat PR titles, issue bodies, and comments as untrusted input wherever an agent reads them, and do not grant the agent's job repository write or secret access it does not need.
- Watch for payloads hidden in HTML comments, invisible in rendered Markdown but still read by the agent, and for fake Trusted Content Section markers crafted to elevate attacker text.
- Confirm
env,whoami,ps auxeww, andcurlstyle tool calls from a CI agent are evaluated at a hook with allow/deny/log, so a comment-triggered command is stopped before it runs. - Verify every tool call is written to a 90-day audit trail and routed to your SIEM, so you can answer scope questions when the next agent prompt-injection disclosure lands.
- Cross-reference this inventory against the sibling OpenAI Codex branch-name command injection advisory to find runners exposed to more than one input-driven execution path.
Comment and Control shows that an agent's everyday work - reviewing a pull request or answering an issue - is an execution and credential path when a comment is treated as trusted instructions. Inventory the agents and CLIs your runners host and govern the tool calls they make at the hook. For the full coding-agent attack surface, see the pillar guide on securing AI coding agents and CLIs, and to see Anomity govern this layer across your fleet, request early access.
Frequently asked questions
What is the Comment and Control prompt injection technique?
Comment and Control is a prompt injection technique disclosed by security researcher Aonan Guan with Johns Hopkins researchers Zhengyu Liu and Gavin Zhong. It hijacks AI coding agents wired into GitHub Actions by planting instructions in PR titles, issue bodies, and comments. The agent reads that attacker text as trusted context, runs the attacker's commands, and exfiltrates the results back through a PR comment, issue comment, or git commit. The entire loop runs inside GitHub with no external server. The Anthropic finding was rated CVSS 9.4 Critical, and Google and GitHub each paid bounties for their respective findings.
How did the attack steal credentials from each agent?
Against the Claude Code Security Review action, a malicious PR title broke the prompt context and made Claude run whoami, ps auxeww, and env, then return the credential dump packaged as a JSON security finding. The Gemini CLI Action (run-gemini-cli) was tricked by a fake Trusted Content Section into posting the GEMINI_API_KEY as a public comment. The GitHub Copilot Agent payload was hidden inside an HTML comment, invisible in rendered Markdown but still read by the agent. Each path moved a secret out through normal GitHub surfaces, so nothing looked like exfiltration to a network or endpoint tool.
Did opening a pull request really trigger the agent with no victim interaction?
Yes. The workflows auto-triggered on the pull_request, issues, and issue_comment events, so simply opening a pull request or filing an issue activated the agent without any victim interaction. A maintainer did not need to click, approve, or comment. That is what makes this class dangerous: the trigger is the same everyday GitHub action a stranger can take against a public repository, and the agent processes the attacker-supplied title, body, or comment as part of its trusted instructions before any human is in the loop.
How does Anomity reduce exposure to Comment and Control?
Anomity inventories AI agents and CLIs on every managed endpoint as part of the eight AI artifact types it tracks, so you can find which runners host the Claude Code, Gemini CLI, or Copilot agent surfaces. On agents that expose a hook, it returns allow, deny, or log on each tool call before it runs, so the env, whoami, and curl style calls these injections attempt can be denied at the boundary. Every decision lands in a queryable 90-day audit trail routed to SIEM, Slack, email, or Jira, so you can answer what an agent actually ran when a comment-driven payload arrives.