DEV Community

Edison Flores
Edison Flores

Posted on

MCP Security Checklist: 6 checks before exposing an MCP server

MCP servers are the new API attack surface. They give LLMs real-world capabilities — filesystem access, database queries, code execution, API calls. But almost none go through a security filter before being exposed.

Here's a 6-point checklist I run on every MCP server before trusting it:

1. AUTH — Is there any?

A surprising number of MCP servers bind to a port without authentication and assume "it's local only." Localhost is not a security boundary on a shared or development machine.

Check: Does the server require a token, API key, or session? Can you connect without credentials?

2. Tool Description Injection

Tool descriptions go directly into the LLM's context window. A malicious or compromised description can instruct the model to exfiltrate data, execute commands, or reveal credentials.

Check: Read every tool description. Look for:

  • "ignore previous instructions"
  • "you are now" / "your new role"
  • Instructions to read specific files (especially credentials)
  • Instructions to send data somewhere
  • "reveal" / "output" + "secrets" / "tokens" / "keys"

Treat tool metadata as untrusted input, not documentation.

3. Input Validation

Tool parameters arrive at real systems (filesystem, database, HTTP). Path traversal and injection apply exactly the same as in a normal API.

Check: Does each tool have an inputSchema? What happens when you send:

  • Path traversal: ../../../etc/passwd
  • SQL injection: ' OR 1=1 --
  • Command injection: ; cat /etc/shadow #
  • SSRF: http://169.254.169.254/latest/meta-data/

4. CORS / Origin

If the MCP server is reachable from a browser context, who can call it?

Check: Is CORS configured? Is it * (allow all origins)? If so, any website can make requests to your MCP server.

5. OAuth / Scopes

If the server acts as a proxy for an external service (GitHub, Slack, Google), are the OAuth tokens scoped minimally or is it "god mode"?

Check: What scopes does the OAuth flow request? Can the server do more than it needs to?

6. Rate Limiting + Error Leakage

Do error responses leak stack traces, secrets, or rate limit information?

Check: Send malformed inputs and rapid requests. Look at error responses for:

  • Stack traces (information leakage)
  • API keys or tokens in error messages
  • Rate limit headers that reveal your throttling strategy

Testing Flow

The flow that works for me: send raw JSON-RPC requests manually (not via a polished client that hides errors), then run a checklist scan.

# Send raw JSON-RPC to see how the server actually responds
echo '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}' | nc localhost 3123
echo '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}' | nc localhost 3123
Enter fullscreen mode Exit fullscreen mode

Automated Approach

I wrote 18 Semgrep rules that automate checks 1-6, plus a Docker sandbox that runs the server with --network none (no internet), --read-only filesystem, and --cap-drop ALL to see what it tries to do at runtime.

The sandbox sends adversarial inputs (path traversal, SQL injection, prompt injection, SSRF) and monitors:

  • stdout for credential/URL/exec mentions
  • filesystem changes via docker diff
  • network attempts (ECONNREFUSED = it tried to connect)
  • crash behavior

The biggest insight: static analysis alone is insufficient. A "text formatter" can look clean in code but try to read ~/.ssh/id_rsa at runtime. The sandbox is what catches that.

Key Takeaway

MCP servers should be treated with the same scrutiny as any external API. The fact that the "caller" is an LLM rather than a human doesn't make it safer — it makes it more dangerous, because LLMs can be manipulated via prompt injection in the tool descriptions themselves.

The --network none Docker flag is the single most effective control. If the server can't phone home, most exfiltration attacks are neutralized even if the code is malicious.


What's your security checklist for MCP servers? The space needs a shared standard.

— Edison Flores

Top comments (0)