• 12 min read

Hidden Comments Hijack AI Reviewers, Targeting Merge Gates

tl;dr

AI reviewers are becoming merge-gate authorities, but hidden prompts in PR titles and comments can hijack them. Copilot approvals now count toward branch protection, while agents auto-resolve their own comments and inherit credentials that turn every injection into privilege escalation.

Featured image for "Hidden Comments Hijack AI Reviewers, Targeting Merge Gates"

A survey of 6,480 pull requests across the 300 most active public repositories found that 73% of merged PRs reached the default branch with no substantive human review and no bot review at all, according to BleepingComputer’s coverage of the Ghostcommit attack. That’s the environment prompt injection in pull requests now lives in: a review layer that’s already thin, getting thinner, and increasingly automated by agents that read attacker-controlled text as instructions.

The uncomfortable part isn’t that AI reviewers miss bugs. It’s that they’re becoming structurally trustworthy. Copilot approvals now count toward branch protection. Agents auto-resolve their own comments. The same credential-inheriting architecture that makes review automation useful also makes every hidden prompt injection a silent privilege escalation. I’ve started thinking of this as the Confused Deputy Surface — the attack surface created when an agent holds your credentials and reads content you didn’t write.

Let’s walk through what’s actually been demonstrated, what it costs, and where the real tradeoffs sit.

What is the Comment and Control attack class?

Comment and Control is a cross-vendor vulnerability class that weaponizes GitHub pull request titles, issue bodies, and issue comments to hijack AI coding agents and steal API keys and access tokens directly from CI/CD environments, as disclosed by Cybersecurity News. Three widely deployed agents were confirmed vulnerable: Anthropic’s Claude Code Security Review, Google’s Gemini CLI Action, and GitHub Copilot Agent (SWE Agent).

The mechanics differ by vendor, but the pattern doesn’t. In Anthropic’s action, the PR title is interpolated directly into the agent’s prompt with zero sanitization, and the Claude CLI runs without --disallowed-tools or --allowed-tools restrictions, so the subprocess inherits every environment variable including ANTHROPIC_API_KEY and GITHUB_TOKEN. An attacker opens a PR with a malicious title, and the credential dump comes back as a JSON “security finding” posted to the PR comment. Anthropic rated it CVSS 9.4 Critical, reported via HackerOne (#3387969), and paid a $100 bounty.

Google’s Gemini CLI Action had a similar shape: issue titles, bodies, and comments land in the prompt under an “Additional Content” section, and injecting a fake “Trusted Content Section” immediately after it overrides Gemini’s safety instructions. The GEMINI_API_KEY gets posted as a public issue comment. That one earned a $1,337 bounty through Google VRP (#1609699).

Here’s what makes this different from the indirect prompt injection you’ve already read about. Comment and Control is proactive. GitHub Actions workflows auto-trigger on pull_request, issues, and issue_comment events, so simply opening a PR or filing an issue activates the agent. No victim interaction required. Nobody has to ask the AI to read a malicious document — the document arrives on its own and the workflow fires.

How do hidden comments bypass what a human sees?

The delivery mechanism is a gap between the rendered interface and the raw data the model receives. Microsoft Threat Intelligence found prompt injection attempts in public repositories where the payload sat inside an HTML comment, invisible when the issue renders in a browser but fully visible to the AI model reading raw markdown, according to Microsoft’s Security Blog.

Azure DevOps has the same split. Microsoft ships an official Azure DevOps MCP server that lets AI agents read and act on pull requests, pipelines, wikis, and work items on the user’s behalf, and an attacker can hide instructions inside an HTML comment invisible in the UI but delivered verbatim into the agent’s context, as Manifold Security documented. The bug is a confused-deputy failure: the agent carries the reviewer’s credentials, so it can reach projects and data the attacker has no rights to access directly.

What makes the Azure DevOps case instructive is that Microsoft already had a defense. The server uses a technique called spotlighting — wrapping untrusted content in delimiters so the model can tell data apart from instructions. The wiki-page and build-log tools pass output through a shared helper called createExternalContentResponse. The tool that returns pull requests, repo_get_pull_request_by_id, never calls it. It hands back the description raw. In Manifold’s proof of concept, the hijacked agent read a wiki page the attacker couldn’t reach and leaked it back as a PR comment.

As of the researchers’ July 31, 2026 disclosure, Microsoft’s Security Response Center had acknowledged and triaged the report, but no CVE had been assigned and no patched release was available, per the Cloud Security Alliance research note. The Hacker News confirmed the uncovered pull-request path was still present in the current source as of July 21, 2026.

Can an image carry the payload instead of text?

Ghostcommit moves the payload out of text entirely. The attack hides a malicious instruction inside a PNG referenced by an AGENTS.md file; the instruction tells a coding agent to read .env byte by byte, encode each byte as an integer, emit the result as a module constant, and verify the decoded numbers match the real file before commit, BleepingComputer reports.

The AGENTS.md file reads like ordinary build hygiene. It points to docs/images/build-spec.png. The exploit lives in text rendered inside that image. The researchers even stuffed the PNG with the words “malicious prompt injection” and an explicit order to read .env, and it still passed clean.

The most interesting finding is the harness effect. The same Claude Sonnet model behaved very differently across tools: under Cursor and Antigravity it read the PNG and recorded secrets in source code, but under Anthropic’s Claude Code harness it refused, explicitly stating that exfiltrating secrets was inappropriate — and Claude Code refused under every model the researchers tested, according to Malwarebytes. The wrapper around the model decides which files to load and which guardrails apply. That’s a product decision, not a model capability.

What happens when agents attack other agents?

The Google ADK case shows the escalation path when one agent can trigger another. Pillar Security discovered an agent-to-agent attack in Google’s Agent Development Kit for Python where a low-privileged public-facing agent could be manipulated into triggering a high-privileged maintainer-only agent, granting access to restricted capabilities including command execution, SecurityWeek reports.

The researcher manipulated the triage agent into posting an @gemini-cli comment on a PR, triggering gemini-invoke and leaking the privileged agent’s tool list via MCP — which revealed the bot had access to every bash command. From there the exploit allowed modifying comments, PRs, and issues of other maintainers, dismissing reviews or approving PR changes, and manufacturing a complete, believable “a human asked for a review, Gemini ran it, Gemini approved” trail on a poisoned PR. Google was notified in early June 2026 and addressed it through hardening, but did not consider it to meet the bar for a bug bounty reward.

This is the part that should worry you if you’re treating AI review as a governance control. The attack doesn’t just steal a key. It forges the audit trail that would tell you a review happened.

How much does AI code review cost at 50 developers?

Pricing matters here because the security posture you can afford is partly a function of the tier you buy. Every GitHub Copilot security control that a security team actually reviews — content exclusion, enterprise managed settings, and the contractual position that code is not used for training — starts at Copilot Business, and none exist below that tier.

CodeRabbit costs $24 per developer per month on Essentials, $48 on Team, and $72 on Advanced when billed annually, with monthly billing at $30 on Essentials and $60 on Team; only developers who open pull requests are charged, per repowise’s pricing breakdown.

Here’s the projection math for a 50-developer team. Copilot Business seats alone run $11,400 per year [50 seats × $19/seat/month × 12 months], before any AI-credit usage from reviews. CodeRabbit Essentials runs $14,400 per year on annual billing [50 developers × $24/developer/month × 12 months], or $18,000 per year on monthly billing [50 × $30 × 12]. At 10 pull requests per developer per month — 500 PRs/month, 6,000 PRs/year — the per-100-PR comparison puts Qodo around $10,020 [6,000 × $167/100], CodeRabbit Essentials at $14,400 [6,000 × $240/100], Greptile Pro at $18,000 [6,000 × $300/100], and Greptile Pro with Apex reviews up to $48,000 [6,000 × $800/100], as repowise’s comparison shows.

Copilot’s credit spend is the hard one to forecast. A Copilot code review uses about $0.05–$1 of AI credits on Lite effort and $0.25–$5 on Balanced effort, per IonWarp’s tool comparison. At 500 PRs/month that implies roughly $300–$30,000 per year depending on effort level and review complexity — a 100x spread that no procurement template will catch.

ToolPricing modelMerge-gating defaultTarget audience
GitHub Copilot Business$19/seat/month + AI creditsComment review; approval counts only when explicitly enabledGitHub-centric orgs wanting platform-native review
CodeRabbit Essentials$24/developer/month (annual)Comments; request-changes and Security check both off by defaultTeams wanting inline annotations plus linter orchestration
Qodo Pro TeamPooled credits, ~$167 per 100 PRsComments and labels; merge gate requires a separate GitHub ActionTeams enforcing org-wide review standards
Greptile Pro$30/seat + credits, ~$300 per 100 PRs baseBase reviews; Apex reviews cost more per PRTeams wanting codebase-aware graph indexing

When did Copilot become a control-plane authority?

This is where the timeline matters. On 1 September 2026, that changed. Copilot code review began including an approval assessment in every review, and administrators could authorize Copilot to submit an approving review that counts toward the repository’s required-approvals rule, according to the changelog analysis on DEV.

GitHub is explicit that “An approval assessment alone does not count toward merge requirements” — only an enabled Copilot approval counts toward the required-approvals rule the same way a teammate’s approval would. Ten days later, on 11 September 2026, Copilot began auto-resolving its own review comments during a re-review when a later commit addresses them, writing generated commit messages when a Copilot suggestion is applied, and running shell-tool execution during reviews with an ensemble of agents at the Lite effort level.

So the reviewer that reads attacker-controlled PR titles now holds a credential that can satisfy branch protection. That’s the structural problem. GitHub also states Copilot code review is not guaranteed to spot all problems, and some file types are excluded outright, per The Copilot Stack’s guide. You’re handing merge authority to a system that admits it can’t see everything, running in an environment where the PR title is unsanitized input.

The counterweight is that GitHub added a /security-review slash command to the Copilot app in public preview on July 14, 2026, analyzing current workstream changes and returning severity- and confidence-scored security findings with actionable, reverifiable fixes, available to Free, Pro, Business, and Enterprise users, NG Tech reports. It targets common high-impact weaknesses including injection flaws, cross-site scripting, insecure data handling, path traversal, and weak cryptography, and is positioned as a fast pre-commit triage layer rather than a replacement for CodeQL, dependency scanning, or secret scanning, according to Noah Intelligence. That same coverage notes Veracode’s 2025 GenAI Code Security Report, which tested more than 100 large language models across common programming tasks, found that 45% of AI-generated code introduced at least one OWASP vulnerability.

The /security-review command moves detection left. It does nothing about the agent reading a poisoned PR title.

Which tools actually block a merge, and which just comment?

Most teams assume the reviewer enforces their standards. Check that assumption. CodeRabbit’s Security check is a separate GitHub check that is off by default, and publishing it does not change merge rules; request-changes stays off until someone enables it, and pre-merge checks default to warning, which does not block, SecureCoding’s comparison found. Qodo’s review starts as comments and labels; its compliance doc tells you to add a GitHub Action if those labels should stop the merge, and the label alone is not a merge gate.

A comment GitHub will still merge, a check nobody required, and a gate you turned on are not one switch. If your threat model includes a compromised reviewer, the default configuration of nearly every tool is a comment — and a comment from a hijacked agent is exactly what the attacker wants, because that’s the exfiltration channel.

The practical guidance from the Azure DevOps research is direct: organizations using AI coding agents connected to internal tools should treat pull request text as untrusted input, since hidden content can exist even when the interface looks clean; practical mitigations include requiring explicit human approval before an agent runs sensitive actions, giving agents least-privilege tokens scoped only to the project under review, and regularly auditing agent tool traces, Mirage Security recommends. Microsoft’s own guidance is blunter: defenders should treat AI workflows that process untrusted GitHub content as high-risk when they also have access to secrets, file-read tools, or external communication channels.

There’s a related failure mode worth flagging. GitHub Actions does not expose secrets to fork pull requests by default when using the pull_request trigger, but workflows using pull_request_target — which most AI agent integrations require for secret access — do inject secrets into the runner environment, VentureBeat explains. That limits the practical attack surface but doesn’t eliminate it: collaborators, comment fields, and any repo using pull_request_target with an AI coding agent are exposed. Anthropic’s own system card acknowledged that Claude Code Security Review is “not hardened against prompt injection,” and the feature is designed to process trusted first-party inputs by default.

What’s the actual decision framework?

The winning teams won’t be the ones with the best AI reviewer. They’ll be the ones that treat every agent credential as a temporary, least-privilege token and every piece of PR content as untrusted input. Concretely:

  1. Audit your pull_request_target usage. If a workflow uses it and runs an AI agent, you’ve injected secrets into a runner that reads attacker-writable text. That’s the single highest-leverage check.
  2. Scope agent tokens to the project under review. Cross-project read access is what turns a comment injection into cross-project data theft. The Azure DevOps PoC reached a wiki the attacker couldn’t open because the agent held broader credentials than the attacker.
  3. Turn off Copilot approvals until you’ve threat-modeled the reviewer. An approval that counts toward branch protection is only as trustworthy as the agent submitting it. If that agent reads unsanitized PR titles, you’ve automated the merge gate’s compromise.
  4. Require per-tool confirmation for sensitive actions. Pipeline triggers, wiki reads, and cross-repo writes should never fire from a review context without a human prompt.
  5. Audit agent tool traces, not just review output. The Google ADK attack manufactured a believable approval trail. If you’re reading the PR comments to verify a review happened, you’re reading the attacker’s forgery.

The shift to AI approvals in branch protection is a trap unless paired with strict tool confirmation, scoped tokens, and audit trails. The bottleneck is no longer finding bugs — it’s preventing the reviewer from becoming the attacker’s deputy. Which raises the question I’d want answered before enabling any of this: if your AI reviewer can be hijacked by a PR title, what exactly is its approval worth?