MCPSafe.io
RegistryThreatsMethodologyDocsPricingScanSign in
MCPSafe.io

Security checks for MCP servers — public packages and private repos, fast or deep.

Legal

Privacy PolicyCookie PolicyTerms of ServiceSecurity disclosure

Resources

State of MCP SecuritySupportSystem statusMade in Germany 🇩🇪

© 2026 MCPSafe. All rights reserved.

GDPR — Privacy Policy
← Threat Catalog

Server Implementation

Insecure direct object references (IDOR)

HIGHAIVSS 7.1CWE: CWE-639OWASP: LLM02Agentic: T03Rule: MCP-045

A tool accepts an identifier (document ID, ticket ID, user ID) and returns the record without verifying that the caller is allowed to see it.

What it is

IDOR is the bug where the server assumes the client will only ask for objects it is allowed to ask for. It is less about the missing check and more about the missing *ownership model* — the tool treats the ID as a fact, not as a claim to authorize.

Why it matters for MCP

MCP tools often wrap existing APIs that already had authorization baked in at the HTTP layer. When you wrap those APIs into a tool the LLM can drive, the authorization gets re-anchored on whatever credentials the server was given at startup — typically a single service account with broad access. The model can now ask for any object the service account could see, including objects the current end-user should not.

Vulnerable example

example.py
1
@server.tool()
2
def get_invoice(invoice_id: str) -> dict:
3
    return db.fetch_one("SELECT * FROM invoices WHERE id = %s", invoice_id)

Secure example

example.py
1
@server.tool()
2
def get_invoice(invoice_id: str, ctx: Context) -> dict:
3
    user_id = ctx.principal.user_id  # set from the MCP auth layer
4
    row = db.fetch_one(
5
        "SELECT * FROM invoices WHERE id = %s AND owner_id = %s",
6
        invoice_id,
7
        user_id,
8
    )
9
    if not row:
10
        raise PermissionError("invoice not found or not yours")
11
    return row

How MCPSafe detects this

We flag database reads that use a tool argument as the primary-key filter without joining to a principal-derived column. This is a heuristic rule — false positives are common, so we surface it as HIGH evidence rather than a certain finding.

See the full threat catalog for every documented detection.

Framework alignment

OWASP LLM Top-10 (2025)
LLM02 — Sensitive Information Disclosure
OWASP Agentic AI Top-10
T03 — Privilege Compromise
AIVSS v0.5
7.1 (HIGH)AIVSS:1.0/S:HIGH/AV:N/AU:L/BR:M/CD:D

Further reading

  • CWE-639: IDOR
  • OWASP API1: Broken Object-Level Authorization

Scan an MCP server for this issue

MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.

Scan now