Privilege escalation via admin-only tools
Privilege escalation via admin-only tools
Summary
An AI agent, connected to an MCP server with more capabilities than its intended task requires, is induced to discover and invoke privileged tools the operator never meant it to call. The escalation almost always rides on a token scoped too broadly — a Personal Access Token with repo + admin:org, a Supabase service_role key, a database superuser, or a cloud IAM role that covers both read and administrative operations. The attacker’s “privilege” is already sitting in the agent’s toolbox; the exploit is convincing the agent to use it.
How it works
- Excess scope baked in at integration time. MCP servers typically authenticate with a single long-lived token. Developers grant broad scopes during setup because narrower scopes require mapping each MCP tool to a specific permission, which most servers do not document. OWASP MCP Top 10 lists this as MCP01 (Token Mismanagement).
- Agent enumerates available tools. On session start, the agent receives the full tool manifest from the MCP server, including admin tools (
delete_user,grant_role,drop_database,create_access_token,set_webhook). - Trigger — either prompt injection or task drift. Two common patterns:
- Indirect prompt injection: untrusted data read by the agent contains an instruction to invoke an admin tool (the Supabase and GitHub patterns above, extended to destructive calls).
- Task drift / excessive agency: a user asks the agent to “clean up my repos” and the agent, reasoning freely, calls
delete_repoon more than intended. OWASP Agentic Top 10 lists this as ASI03 (Identity & Privilege Abuse) and Excessive Agency.
- Admin tool executes with full authority. There is no second authentication; the MCP server trusts the already-issued token.
- Persistence. The agent can create new credentials, webhooks, deploy keys, or service accounts to keep access after the session ends. Arun Baby’s “privilege escalation kill chain” writeup describes AI agents self-granting permissions across sessions.
Real-world examples
GitHub MCP — admin-scope PATs (May 2025)
In the Invariant Labs GitHub disclosure, the PAT held repo scope covering public and private repos. The same class of PAT in practice often also holds admin:org or workflow, meaning a prompt-injected agent could in principle:
- create or modify GitHub Actions workflows (
workflowscope) - add SSH deploy keys
- invite organisation members (
admin:org)
Invariant’s proof-of-concept did not demonstrate org-admin escalation, but the architectural finding — that one PAT covers everything the human can do — is the escalation primitive. (Invariant Labs)
Supabase MCP — service_role bypass of RLS (July 2025)
The Supabase incident is simultaneously a data-exfiltration story and a privilege-escalation story: the agent could, in principle, have invoked DROP TABLE, CREATE USER, or other administrative SQL with exactly the same ease as the SELECT the attacker demonstrated. service_role is, by design, a superuser key. Pomerium’s “When AI Has Root” post focuses on this framing. (Pomerium)
SQLite MCP — stored prompt injection as escalation primitive (2025)
Research on the SQLite MCP server showed that SQL injection into tables the agent later reads creates a “stored prompt injection” that survives across sessions. Because the agent is authenticated with write capability, a one-shot SQL injection plants instructions that will be executed with agent authority on every subsequent read. (Trend Micro — “Why a Classic MCP Server Vulnerability Can Undermine Your Entire AI Agent”)
Ecosystem scale
Academic analysis of ~5,200 open-source MCP server implementations found 43% had command injection flaws and 30% permitted unrestricted URL fetching — both of which can be converted into privilege escalation on the host the MCP server runs on. (arXiv 2508.12538)
Impact
- Destructive operations on production resources. Dropped tables, deleted repos, revoked keys, terminated compute.
- New persistence mechanisms. Attacker-controlled webhooks, deploy keys, OAuth apps, IAM users created by the agent survive token rotation.
- Compliance breach. An agent invoking
admin:orgordrop_databaseis, by most SOC 2 / ISO 27001 control frameworks, an unaudited privileged action. - Blast radius equals token scope. A PAT that can reach 200 repos can destroy 200 repos.
Detection
- Tool-frequency baselining. An agent whose usual manifest is
get_issue,list_pull_requests,create_commentsuddenly invokesdelete_repoorset_webhook. This is an outlier on both the tool and the calling agent. - Admin verb lexicon. Alert on any tool name matching
delete_*,drop_*,grant_*,set_*_token,create_*_key,revoke_*,transfer_*. - First-time tool use per session. If an agent has never invoked tool X in the last 90 days and invokes it today, treat as high-signal.
- Out-of-hours or out-of-scope resources. Admin calls targeting resources outside the agent’s declared project.
- Correlation with prior read of untrusted content (same signal as exfiltration — admin escalation rides the same vector).
Prevention
Transport-layer policy lets you strip admin tools from the manifest the agent sees, or deny them outright at call time. This is how Intercept is designed.
Default-deny policy (mirrors testdata/default_deny_policy.yaml):
version: "1"
description: "GitHub MCP — deny admin tools"
default: "deny"
tools:
# Explicitly allow only the tools this agent needs.
get_issue:
rules: []
list_issues:
rules: []
get_file_contents:
rules: []
create_comment:
rules:
- name: "hourly comment limit"
rate_limit: 10/hour
on_deny: "Hourly comment limit reached"
# Everything else — create_repo, delete_repo, admin:*, set_webhook — blocked
# by default:deny.
Speculative example — neutralise admin verbs on a permissive server:
# Speculative. Illustrative.
version: "1"
description: "Block admin verbs on Supabase MCP"
default: "allow"
tools:
execute_sql:
rules:
- name: "block DDL"
conditions:
- path: "args.query"
op: "matches"
value: "(?i)^(drop|truncate|alter|create user|grant|revoke)"
on_deny: "DDL and privilege statements not permitted from agents"
delete_customer:
rules:
- name: "block destructive action"
action: "deny"
on_deny: "Customer deletion not permitted via AI agents"
Non-policy controls that must accompany this:
- Dedicated least-privilege agent role per integration. Never reuse developer PATs or
service_rolekeys. - Separate MCP server instances for read vs write workloads — the agent sees a different manifest depending on task.
- Step-up auth (human-in-the-loop approval) on any admin verb.
- Short-lived tokens — the MCP 2025-11-25 spec and OWASP MCP01 both mandate this.
Sources
- Invariant Labs — “GitHub MCP Exploited” (26 May 2025)
- Invariant Labs — “Toxic Flow Analysis in Agentic Systems”
- Pomerium — “When AI Has Root: Lessons from the Supabase MCP Data Leak”
- Trend Micro — “Why a Classic MCP Server Vulnerability Can Undermine Your Entire AI Agent”
- OWASP MCP Top 10 — MCP01:2025 Token Mismanagement
- OWASP Top 10 for Agentic Applications — ASI03 Identity & Privilege Abuse
- Elastic Security Labs — “MCP Tools: Attack Vectors and Defense Recommendations”
- Arun Baby — “The privilege escalation kill chain: how AI agents self-grant permissions”
- arXiv 2508.12538 — “Systematic Analysis of MCP Security”
Related attacks
- Data exfiltration via tool chaining
- Credential leak via error messages
- Tool poisoning (malicious tool descriptions)
Protect your agent in 30 seconds
Scans your MCP config and generates enforcement policies for every server.
npx -y @policylayer/intercept init