Skip to main content
Glama
ibrahimsaleem

MCP Security Lab

MCP Security Lab

A small, real, runnable Model Context Protocol setup with seven deliberate vulnerabilities — and their fixes — so you can see each risk actually work instead of just reading about it. Built against the current official MCP spec (2026-07-28) and its security best practices doc, plus the OWASP MCP Top 10.

Everything runs locally. Nothing here talks to a real system you care about.

Documentation

Everything below is readable straight on GitHub — no server needed — and each doc links to the next:

  • docs/owasp-mcp-top10.md — field reference for all ten OWASP MCP Top 10 risk categories, what an MCP server actually is, the end-to-end request path and its three named risk zones, and a link from every category straight to the exploit script that demonstrates it (or the closest one).

  • docs/mcp-stateless-rewrite.md — before/after architecture diagrams for the 2026-07-28 spec's stateless rewrite, a ranked priority list of which OWASP categories are now more critical because of it, a table mapping every spec/roadmap change to a specific OWASP category, and five new vulnerability patterns with concrete failure scenarios.

The same two pages also exist as live, interactive HTML inside the dashboard (guidelines.html and rewrite.html, see Dashboard below) — the content is identical, the dashboard version just links directly into the live exploit runner instead of a source file.

Related MCP server: Damn Vulnerable Model Context Protocol (DVMCP)

What's covered

File tool

Vulnerability

Source

run_diagnostics

Command Injection

OWASP MCP05

search_docs / get_secret_config

Tool (Description) Poisoning

OWASP MCP03

get_cart

State Handle Hijacking

MCP Security Best Practices

proxy_fetch_data

Token Passthrough / Confused Deputy

MCP Security Best Practices

read_user_file

Insufficient Auth + No Audit Trail

OWASP MCP07 / MCP08

read_calendar_events

Privilege Escalation via Scope Creep

OWASP MCP02

launch_from_config

Client Launch Injection (Supply Chain RCE)

OWASP MCP04 · 2026 research

servers/vulnerable_server.py has all seven, broken on purpose. servers/fixed_server.py has the same seven tools, patched — run the same exploit against both and watch the outcome flip.

Every OWASP MCP Top 10 category now links to a demo (or the closest real one) from the dashboard's guidelines page — including MCP09 (Shadow MCP Servers), which is a governance gap rather than a single-tool-call bug, so it's illustrated by the lab itself rather than a dedicated exploit script.

Staying current

MCP moves fast — the 2026-07-28 spec release was the protocol's biggest rewrite yet (it went fully stateless), and a new roadmap covering the next release was published just days ago, on 2026-08-22. Two places track what's changed since this lab was built and how it shifts the risk picture:

  • docs/owasp-mcp-top10.md — the "What's changed" section, or the live version at http://127.0.0.1:8000/guidelines.html#2026-updates.

  • docs/mcp-stateless-rewrite.md — the full breakdown, including which OWASP categories are now more critical and why, or the live version at http://127.0.0.1:8000/rewrite.html.

Setup

python -m venv .venv
source .venv/bin/activate         # Windows: .venv\Scripts\activate
pip install -r requirements.txt

Verified against mcp SDK v1.26.0 — the servers import FastMCP from mcp.server.fastmcp (some tutorials show it imported straight from mcp.server, or reference a MCPServer class from a mcp.server.mcpserver module that doesn't exist in this SDK line; same API either way). If your installed version differs, pip show mcp and check dir(mcp.server) for the right class name — everything else (the .tool() decorator, .run(transport="stdio")) is unchanged.

The command-injection exploit works even without a real ping binary on your machine — the point is proving the shell metacharacter (;) gets interpreted at all, which the "PWNED" marker file confirms.

Set whichever key(s) you want to use as environment variables — never put a real key in a file you might commit or paste into a chat:

export OPENAI_API_KEY="sk-..."
# and/or
export GEMINI_API_KEY="AI..."

Run the exploits

Six of the seven don't need an LLM at all — they call the MCP server directly to prove the flaw lives in the server, not in model behavior:

# Command injection
python exploits/exploit_cmd_injection.py servers/vulnerable_server.py
python exploits/exploit_cmd_injection.py servers/fixed_server.py

# State handle hijacking (guessing another user's cart ID)
python exploits/exploit_state_hijack.py servers/vulnerable_server.py
python exploits/exploit_state_hijack.py servers/fixed_server.py

# Token passthrough / confused deputy
python exploits/exploit_token_passthrough.py servers/vulnerable_server.py
python exploits/exploit_token_passthrough.py servers/fixed_server.py

# Insufficient auth + no audit trail (reading another user's file by ID)
python exploits/exploit_auth_audit.py servers/vulnerable_server.py
python exploits/exploit_auth_audit.py servers/fixed_server.py

# Privilege escalation via scope creep (redirecting a read-only tool's token)
python exploits/exploit_scope_creep.py servers/vulnerable_server.py
python exploits/exploit_scope_creep.py servers/fixed_server.py

# Client launch injection / supply chain RCE (untrusted config picks command/args)
python exploits/exploit_launch_injection.py servers/vulnerable_server.py
python exploits/exploit_launch_injection.py servers/fixed_server.py

Tool poisoning needs a real model, because the vulnerability is whether the model follows hidden instructions in a tool's own description:

python exploits/exploit_tool_poisoning.py servers/vulnerable_server.py openai
python exploits/exploit_tool_poisoning.py servers/vulnerable_server.py gemini
python exploits/exploit_tool_poisoning.py servers/fixed_server.py openai

Dashboard

A local web dashboard shows all 7 vulnerabilities as cards, lets you view the vulnerable-vs-fixed code diff for each, and click a button to run the real exploit script against either server — the output streams into a live terminal panel in the browser and ends with a VULNERABLE/SAFE verdict.

pip install -r requirements.txt -r ui/requirements.txt
uvicorn ui.server:app --reload --port 8000

Then open http://127.0.0.1:8000. Set OPENAI_API_KEY / GEMINI_API_KEY in the terminal you launch uvicorn from if you want to run the tool-poisoning card — the dashboard never asks for a key itself, it just reads whichever of those environment variables are already set on the machine running it.

Talk to it yourself

agent.py is a general-purpose MCP client + agent loop — point it at either server and either provider and chat with it interactively:

python agent.py servers/vulnerable_server.py openai
python agent.py servers/fixed_server.py gemini

Try asking it to search the docs, check a cart, or run diagnostics on a host, and watch the [llm -> tool] / [tool -> llm] lines to see exactly what it decided to call and what came back.

What's NOT fully covered here

Two things from the current MCP security doc are real but harder to demo in a small local lab, worth reading about even if you don't build them:

  • SSRF via OAuth discovery — a malicious server pointing a client's metadata fetch at 169.254.169.254 (cloud instance metadata). Needs an actual OAuth flow and a network to attack.

  • Mix-up / localhost redirect URI impersonation — needs a real multi-authorization-server setup to demonstrate meaningfully. The 2026-07-28 spec added a concrete mitigation for this (clients must now validate the iss parameter, RFC 9207, before redeeming an auth code) — see the guidelines page's "2026 Updates" section.

Both are described in detail at https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices.

Extending this

  • Add another vulnerable tool and its exploit script following the same pattern: comment the flaw, write the exploit, write the fix.

  • Try running the same exploit against a real third-party MCP server you install (with permission, on infra you own) — the state-hijack and no-auth patterns show up constantly in quickly-built servers.

  • Wire AUDIT_LOG in fixed_server.py into a real log sink and build a small detection rule for the .denied events — that's basically MCP08 (audit/telemetry) made concrete.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.

  • MEOK MCP Hardening MCP — automated security red-team for any MCP server. Maps OWASP LLM Top 10

  • Scans MCP servers for tool poisoning, prompt injection and supply chain risks.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ibrahimsaleem/mcp-security-lab'

If you have feedback or need assistance with the MCP directory API, please join our Discord server