AIDEFEND in Action AIA-0097 Validated Research Published: Oct 1, 2026

Azure DevOps MCP Review Agent Cross-Project Exfiltration

Manifold Security showed that an HTML comment hidden in an Azure DevOps PR description was returned verbatim by the official MCP server's PR tool. Claude Code and Copilot CLI agents reviewing the PR followed it to run a pipeline and read a wiki in a project the contributor could not access, then posted the wiki content as a comment on the contributor's PR. MSRC acknowledged and triaged the report; the cited post did not confirm a fix.

Indirect Prompt InjectionData ExfiltrationSink EnforcementMCP Security
9 applicable AIDEFEND defenses

Threat Analysis

The contributor's hidden HTML comment was invisible to a human reviewer but not to the MCP PR tool. The review agent held broader Azure DevOps rights than the contributor, so obeying the comment turned a normal PR review into a cross-project pipeline run, private wiki read and attacker-visible comment.

  1. A contributor embeds an HTML comment that looks invisible in the web UI but asks an AI reviewer to run a pipeline, read a private wiki, and post it back.
  2. The reviewing agent calls get_pull_request; unlike some other server tools, the PR description is returned without the source's spotlighting wrapper.
  3. Following the injected text, the agent uses pipelines_run_pipeline under the reviewer's credentials in a project the contributor cannot access.
  4. The agent invokes wiki_get_wiki_page_content to read confidential content from that private project.
  5. The agent writes the wiki content as a comment on the contributor's PR, a lower-trust destination that the attacker can read.

Manifold demonstrated the chain with Claude Code and Copilot CLI in tests. MSRC acknowledged and triaged the report. The cited disclosure does not say Microsoft fixed the PR-description tool, and spotlighting untrusted text alone is weaker than per-action authorization.

Applicable AIDEFEND Defenses (9)

AID-H-018.002
Policy-Based Access Control
Very High
Bind the review task to its authorized project and action and deny a cross-project run even when the reviewer account could perform it interactively. The reader-owned enforcement point is a policy hook in the agent's dispatcher (a Claude Code PreToolUse hook or Copilot CLI tool policy) or an MCP gateway in front of the Azure DevOps server, which rejects any pipelines_* or wiki_* call whose project argument differs from the PR's project; Microsoft's server handler is not where the customer can put this decision.
AID-H-017.002
Least-Privilege Tool Architecture
Very High
Start the review MCP server with only core and repositories domains (-d core repositories; core is required), so pipeline and wiki tools are not registered. Authenticate a dedicated server identity under H-004.002 and separately constrain its project authorization under H-018.002. Authentication itself does not grant or deny project permissions. Verify that direct API paths cannot bypass the restricted tool population.
AID-H-004.002
Service & API Authentication
High
Authenticate the reviewer MCP server as a dedicated Entra service principal through a supported non-interactive credential flow, not an administrator's user session. Separately grant that identity only the reviewed project's necessary code/PR permissions and deny unrelated pipelines and private wikis. OAuth establishes machine identity; project authorization is a separate prerequisite. Independently probe cross-project operations under the exact server identity and require denial.
AID-H-018.005
Value-Level Capability Metadata & Data Flow Sink Enforcement
Medium
For a customer-controlled review runtime, propagate authoritative wiki sensitivity/provenance to every derived value and enforce the canonical PR-comment sink under H-018.005. A gateway that merely labels returned text cannot track arbitrary model paraphrasing or encoding. A conservative alternative is to mark the whole isolated review session confidential after a private read and deny all lower-trust writes until a fresh session; this is not the published value-level tracking method. Both approaches need complete read/write coverage, trusted session binding, no direct API bypass and fail-closed unknown labels. Stock CLI behavior is not proof of deployment.
AID-H-018.003
High-Impact Independent Validation & Approval Gate
Medium
Require independent, fresh approval bound to the exact project, pipeline, tool arguments and effect before a controlled dispatcher or MCP gateway executes a high-impact cross-project action. Native CLI prompts can support review but are not G001's signed action-bound gate and cannot guarantee the reviewer will reject an injected request. Unattended runs deny missing approval and every bypass path must enforce the same gate.
AID-H-017.007
Dual-LLM Isolation Pattern
Medium
Let a separately isolated Q worker without tools read raw PR text and diffs; a validating broker emits only a bounded domain projection for the P worker. Separate identities, credentials and network paths, and deny P access to raw PR content. Typed strings may still contain malicious instructions, so projected prose remains untrusted and every tool action needs independent authorization. Stock Claude Code or Copilot CLI does not provide this architecture merely by using a second prompt.
AID-D-003.004
Tool-Call Sequence Anomaly Detection
Medium
Detect an unexpected transition from PR review into `pipelines_run_pipeline` or `wiki_get_wiki_page_content` using complete tool-call sequence telemetry. The selected howTo can identify an unapproved tool transition; it cannot infer that the target project differs from the PR project unless the event stream is separately enriched with validated project IDs and the task's approved project. Treat project mismatch as an additional custom detector, not an inherent output of this guidance.
AID-D-003.002
Sensitive Information & Data Leakage Detection
Medium
Scan every comment the review agent is about to post for organization-specific markers such as internal project names, wiki page titles and credential formats, and raise a finding before release. The finding feeds the sink policy in AID-H-018.005; it does not block by itself, but it catches provenance that taint tracking missed.
AID-H-034.005
MCP Server Output, Resource URI & Elicitation Boundary Controls
Medium
Bound and label attacker-editable PR fields as untrusted MCP output before returning them to the model. The existing spotlighting gap should be closed, but labeling alone is not an authorization gate. This runs inside the server: with the official server the reader can wait for Microsoft's fix, run the open-source server from a patched fork, or wrap its outputs in an MCP gateway.

What Defenders Should Do Now

  • Treat MCP-returned PR descriptions as untrusted, including HTML comments hidden in the web UI.
  • Load only required review domains, authenticate a dedicated service principal and constrain Azure DevOps project permissions. Use a trusted dispatcher or gateway to authorize each task, PR and project; deny unrelated pipeline and private-wiki operations.
  • If private-wiki access is necessary, implement complete value and derivation tracking in a controlled runtime and enforce the PR-comment sink. A gateway that only labels source text cannot track model rewriting. A conservative alternative marks the entire isolated session confidential after a private read and denies lower-trust writes until a fresh session. This is not the published value-level tracking method; both approaches require complete read/write coverage.

1 additional consideration

Evidence and deployment boundary

The original source verifies the PoC and server-output gap, but supplies no confirmed production compromise or completed Microsoft patch.
Recommendation: Treat PR descriptions and comments returned by the MCP server as untrusted data, including HTML comments not rendered in the web UI.

Conclusion

AIDEFEND  maps the case to a minimal MCP tool population, constrained backend project permissions and final tool authorization. Tasks that require confidential reads also need complete runtime derivation and sink coverage, or an explicitly bounded whole-session fencing alternative. Prompts and source labels alone cannot guarantee prevention.

Last updated: