MCP security: a vulnerable MCP server you can run, with three flaws and their fixes. Sources and run output Read and run on 13 November 2026 (first run 12 November 2026). Published by Excession Labs. Post: https://excessionlabs.ai/blog/mcp-security/ Repository: https://github.com/Excession-Labs/mcp-security-fixture (commit 194b4a6) Files in this folder results.csv the 16 results (8 checks x 2 modes), copied from the repository at commit 194b4a6 run.sh the reproduction script, copied from the repository at commit 194b4a6 README.txt this file SHA256SUMS hashes of the files above ===================================================================== 1. Run of run.sh ===================================================================== Command: ./run.sh (in the repository folder; loopback only, 127.0.0.1; fake data) Date: 13 November 2026. The same command gave the same results on 12 November 2026. Environment: uv 0.10.4, Python 3.13.12, mcp 2.3.0. Exit code: 0. Wall time: about 4.5 s with the environment already installed. results.csv after the run is identical to the file in this folder. Output: 1_tool_description_injection vulnerable stub_agent_leaks_secret_to_tool exploited 1_tool_description_injection vulnerable description_scanner detected 1_tool_description_injection fixed stub_agent_leaks_secret_to_tool blocked 1_tool_description_injection fixed description_scanner clean 2_token_passthrough vulnerable downstream_received_clients_token exploited 2_token_passthrough vulnerable tool_still_works ok 2_token_passthrough vulnerable replay_mcp_token_at_downstream exploited 2_token_passthrough fixed downstream_received_clients_token blocked 2_token_passthrough fixed tool_still_works ok 2_token_passthrough fixed replay_mcp_token_at_downstream blocked 3_missing_authorization vulnerable alice_reads_bobs_invoice exploited 3_missing_authorization vulnerable alice_reads_own_invoice allowed 3_missing_authorization vulnerable no_token_rejected rejected 3_missing_authorization fixed alice_reads_bobs_invoice blocked 3_missing_authorization fixed alice_reads_own_invoice allowed 3_missing_authorization fixed no_token_rejected rejected results.csv rows: 16 ALL AS EXPECTED Counts: 4 attack checks exploited in vulnerable mode, the same 4 blocked in fixed mode. 1 scanner check (detected, then clean). 3 control checks (ok, allowed, rejected) with the same answer in both modes. ===================================================================== 2. Sources ===================================================================== Each page was fetched on 13 November 2026 (HTTP 200). Line breaks inside quotes are removed. Each quote in the post was matched by string against the page text. 2a. MCP specification version https://modelcontextprotocol.io/docs/2026-07-28/learn/versioning (https://modelcontextprotocol.io/specification/versioning redirects here.) - "The current protocol version is 2026-07-28." The specification index at https://modelcontextprotocol.io/specification/2026-07-28 is labelled "Version 2026-07-28 (latest)". 2b. MCP specification 2026-07-28, Authorization Security Considerations https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization/security-considerations Part of https://modelcontextprotocol.io/specification/2026-07-28/basic/authorization Section "Access Token Privilege Restriction". - "The access token used at the upstream API is a separate token, issued by the upstream authorization server. The MCP server MUST NOT pass through the token it received from the MCP client." - "take all necessary steps to ensure no data is returned to unauthorized parties" (full sentence: "MCP servers MUST validate access tokens before processing the request, ensuring the access token is issued specifically for the MCP server, and take all necessary steps to ensure no data is returned to unauthorized parties.") 2c. MCP specification 2026-07-28, Security Best Practices https://modelcontextprotocol.io/docs/2026-07-28/tutorials/security/security_best_practices (https://modelcontextprotocol.io/specification/2026-07-28/basic/security_best_practices redirects here.) Section "Token Passthrough": - "where the downstream API may incorrectly trust the token as if it came from the MCP server or assume the token was validated by the upstream API" (full sentence: "If the MCP server not only accepts tokens with incorrect audiences but also forwards these unmodified tokens to downstream services, it can potentially cause the "confused deputy" problem, where the downstream API may incorrectly trust the token as if it came from the MCP server or assume the token was validated by the upstream API.") - Mitigation: "MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server." Section "Confused Deputy Problem" (not modelled in the fixture): proxy servers that use static client IDs, dynamic client registration and consent cookies. Sections listed in the post as not tested: Server-Side Request Forgery (SSRF), State Handle Hijacking, Local MCP Server Compromise, OAuth Authorization URL Validation, stdio Transport Security in Proxy Scenarios, Mix-Up Attacks, Localhost Redirect URI Impersonation, CIMD Trust Policies, Scope Minimization. 2d. Invariant Labs, "MCP Security Notification: Tool Poisoning Attacks" https://invariantlabs.ai/blog/mcp-security-notification-tool-poisoning-attacks Page date: 2025-04-01. - "A Tool Poisoning Attack occurs when malicious instructions are embedded within MCP tool descriptions that are invisible to users but visible to AI models." - "a specialized form of indirect prompt injections" - "Many client implementations don't properly sanitize, review, or show included tool descriptions to the user." 2e. OWASP Gen AI Security Project, "LLM01:2025 Prompt Injection" https://genai.owasp.org/llmrisk/llm01-prompt-injection/ - "Indirect prompt injections occur when an LLM accepts input from external sources, such as websites or files." 2f. OWASP API Security Top 10, "API1:2023 Broken Object Level Authorization" https://api-security.owasp.org/editions/2023/en/0xa1-broken-object-level-authorization/ - "by manipulating the ID of an object that is sent within the request" - "check if the logged-in user has access to perform the requested action on the record in every function that uses an input from the client to access a record in the database" 2g. MCP Python SDK, migration guide to version 2 https://py.sdk.modelcontextprotocol.io/v2/migration/ States that the FastMCP class was renamed to MCPServer. ===================================================================== 3. Site pages the post quotes ===================================================================== /blog/prompt-injection-defenses/: 69 of 300 attack trials (23.0%) succeeded with no defense. /blog/vulnerability-scanner-vs-penetration-test/: no setup found any of the six authorization fixtures. /ai-red-teaming/ scope list: "MCP servers: what each tool exposes, who may call it and what it returns." /api-penetration-testing/: "Object-level access: can account B read, change or delete account A's record by its ID?" ===================================================================== 4. Not used ===================================================================== The post makes no claim that Excession Labs tests hosted MCP servers. No hosted or third-party server was tested. The post does not map the flaws to an OWASP MCP list.