← Attack Database

Privilege escalation via admin-only tools

Credential & data partial

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

  1. 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).
  2. 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).
  3. 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_repo on more than intended. OWASP Agentic Top 10 lists this as ASI03 (Identity & Privilege Abuse) and Excessive Agency.
  4. Admin tool executes with full authority. There is no second authentication; the MCP server trusts the already-issued token.
  5. 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 (workflow scope)
  • 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:org or drop_database is, 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_comment suddenly invokes delete_repo or set_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_role keys.
  • 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

  • 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
github.com/policylayer/intercept →
// GET IN TOUCH

Have a question or want to learn more? Send us a message.

Message sent.

We'll get back to you soon.