ACVE-2026-0216
Broad GitHub MCP tokens let public issue content exfiltrate private repository data.
The configuration
- Configuration label
- github-mcp-server + untrustedInput=true + approval never|allowlist
- Affected entries
AgentHarness: any — ECOSYSTEM (introduced 0)
- Matcher
- all
- all
- some mcpServers
registryNameeq"github-mcp-server"
- some tools
untrustedInputeqtrue
- some mcpServers
approvalin[ "never", "allowlist" ]
- all
- all
Threat
- Attacker
- content-author
- Vector
- data-exfiltration
- Outcome
- exfiltration
Evidence
| Benchmark | Metric | Value | n | Setup | Link |
|---|---|---|---|---|---|
| GitHub MCP toxic-flow demonstration | asr | — | — | allowlist; github-mcp-server public issue read, create_pull_request, push | https://invariantlabs.ai/blog/mcp-github-vulnerability |
Why it is exploitable
What the vulnerability is
The GitHub MCP toxic-flow demonstration shows indirect content moving across a trust boundary: a malicious public issue causes a Claude 4 Opus agent to read private repositories and post salary or personal data in a public pull request. The MCP server offers per-call confirmation, but users commonly enable Always Allow. R7 records an incident, not an ASR, so this advisory describes a demonstrated data-exfiltration path rather than a percentage. The tool is a real GitHub service, not a simulated benchmark.
Which configuration is exposed
The exposed setup is github-mcp-server with a token that can reach more than one repository, plus a tool that reads public issue or pull-request content and write-capable operations such as create_pull_request or push. Approval is auto or an Always Allow equivalent. A recognisable example is Claude Desktop connected to GitHub MCP with a broad personal token and a user who pre-approved the write tools. untrustedInput comes from public GitHub content; egress is the public repository write.
How ACVE detects it
ACVE matches a GitHub MCP server, a tool marked untrustedInput, and approval never or allowlist. The lock does not presently prove token scope from the server name, so a visible broad token is a confirmed configuration while missing scope metadata is possible. ACVE also cannot observe whether a user clicked Always Allow during a session unless discovery records it. The incident’s real safeguard boundary must be represented in the lock and reproduction notes.
Fix
- Reconfigure mcp:github-mcp-server:token-scope to a single-repository fine-grained token per session. 2. Keep approval on for create_pull_request, push, and any permission-changing call. 3. Put an MCP-scan proxy or equivalent content inspection layer between public issue reads and write tools. 4. Revoke and rotate any token exposed during a toxic-flow test, then verify that a public issue cannot create a private-data pull request.
Grounding needed
Pin the github-mcp-server version, token scopes, repository fixture, issue text, Claude model id, Desktop surface, approval setting, and proxy configuration. R7 confidence is M: Invariant Labs provides a verified incident demonstration, but no rate or benchmark suite exists. Severity is LOW because there is no attacker-budget ASR to feed to severityFromAsr; the consequence is nevertheless concrete exfiltration and should not be described as a mere file write.
Underlying CVEs / aliases
No CVE assigned. behavioural — no code defect; evidence is an evaluation
Detect
npx @pickbitsai/acve audit
For CI, emit SARIF with npx @pickbitsai/acve audit --format sarif --out acve.sarif --apply and upload it with GitHub code scanning.
Fix
Scope GitHub MCP tokens per repository and keep write approvals on.
| Action | Target | To | Why |
|---|---|---|---|
| reconfigure | mcp:github-mcp-server:token-scope | single-repo | A per-session fine-grained token prevents a public issue flow from reaching unrelated private repositories. |
| reconfigure | agent.approval | ask | Keep create_pull_request and push behind an explicit confirmation. |
| reconfigure | defence:mcp-scan-proxy | on | Inspect public issue and pull-request content before it reaches write-capable tools. |
Validation
No validation entries recorded.
Grounding
No grounding checks recorded.