MCP Security: Threat Model, Spec Rules, and a Checklist
MCP security means controlling which servers, tools and credentials an AI client can reach, and assuming any of them might misbehave. Connecting over MCP doesn't make a server trustworthy. The practical fix is a short checklist: know what's connected, switch on only the tools you need, protect your keys, and be ready to revoke.
Step by step
- Inventory what's actually connected. List every MCP server any client on your team can reach, including ones added ad hoc in an IDE config. OWASP's MCP09 "shadow servers" are the ones nobody remembers enabling.
- Turn on only the tools you need. Enable read tools first. Leave write and destructive tools off until a specific workflow needs them, and re-check the list whenever you add a new client to the same server.
- Verify the enabled set over the wire. Compare the tool list your client receives with the instance's enabled tools, then make one harmless call to an enabled tool. The MCPifex quickstart has a curl script that lists tools over the wire.
- Prefer the header form of any bearer token. Use an Authorization: Bearer header wherever the client supports it. Treat any key inside a URL, including MCPifex's path-segment form, like a password that must never be logged or shared.
- Revoke on any sign of compromise. Revoke the credential as soon as a call log shows something you didn't run. Investigate after, not before.
A five-step hardening checklist
Do these before you connect a client to a new server. It takes about ten minutes.
1. List what's connected
Write down every client, server URL or local command, owner and purpose. Include project-level IDE configs and experiments. Remove what nobody uses. OWASP calls forgotten servers "shadow MCP servers", and they're the ones nobody remembers enabling.
2. Enable only the tools you need
Start with read tools, and give the underlying account access to only the data the task needs. Read access can still leak sensitive rows. For every write tool, note what it does and who approves it. A tool's description enforces nothing.
3. Check what the client actually sees
Compare the tool list your client receives with the tools you meant to enable. Then make one harmless call to a tool you turned on. For MCPifex, the quickstart has a curl script that lists the tools over the wire.
4. Protect the credential
Use an Authorization: Bearer header wherever the client supports it. Keep keys out of prompts, screenshots, repos and shared traces. If a client needs the key inside the URL, treat the whole URL as a password.
5. Revoke first, investigate second
If a call log shows something you didn't run, revoke the key straight away. Then look into it. Revoking a gateway key doesn't rotate the database password behind it or undo anything that already happened, so check the upstream account too.
A concrete example
Say you connect a PostgreSQL server to your AI client. Left wide open, the model could run INSERT, UPDATE or DELETE on a bad instruction or a poisoned prompt. Instead, you enable only the four read tools and use a database account that can read one schema. Even if the model is tricked, the worst outcome is a bad read of data you already chose to expose.
The PostgreSQL server on MCPifex works this way. Its execute tool starts off, and its connect_db tool is always refused, so a compromised client can't repoint your credentials at another database.
What the MCP spec says about authorization
The MCP authorization specification makes authorization optional. It defines an OAuth-based flow for HTTP servers that want it. Local stdio servers get credentials from their environment instead.
Where OAuth is used, tokens go in the Authorization header on every request, and the server must check the token was issued for it. Passing a client's token on to another service is explicitly forbidden: a server "MUST NOT accept any tokens that were not explicitly issued for the MCP server."
Risks worth knowing
The 2025-11-25 security guidance lists these. Use them as a review list, not a complete catalog of the current spec:
- Confused deputy: a static client ID plus a lingering consent cookie lets an attacker's client skip consent and steal an authorization code. Ask for consent per client.
- Token passthrough: forwarding a client's token downstream unchecked.
- SSRF: a malicious server points OAuth discovery at an internal address such as the cloud metadata endpoint
169.254.169.254, and an unhardened client follows it. - Session theft: older deployments must bind session IDs to authenticated users. The 2026-07-28 revision removes protocol sessions, but any state you pass through explicit handles still needs access checks.
- Local server compromise: a
stdioserver has the same file and network access as the user who launched it. - Over-broad scopes: asking for every scope up front turns one leaked token into full access.
Tool poisoning
A tool's description and its output are both untrusted input to the model. OWASP defines tool poisoning as hidden instructions in a tool's metadata or output that the model follows as if the developer wrote them.
Invariant Labs showed a working case in 2025: an "add two numbers" tool whose description told the model to leak SSH keys, and a permissive client did it unseen. Reading descriptions before you install helps, but the real defense is limiting what a tool can reach.
OWASP's MCP Top 10
The OWASP MCP Top 10 is a community project, still in beta as of September 2026. Its categories are:
- MCP01 Token Mismanagement / Secret Exposure
- MCP02 Privilege Escalation via Scope Creep
- MCP03 Tool Poisoning
- MCP04 Software Supply Chain / Dependency Tampering
- MCP05 Command Injection
- MCP06 Intent Flow Subversion
- MCP07 Insufficient Authentication / Authorization
- MCP08 Lack of Audit / Telemetry
- MCP09 Shadow MCP Servers
- MCP10 Context Injection / Over-Sharing
Walk through it against one real workflow to find gaps. Don't treat "we cover ten categories" as proof of safety.
Self-hosted or hosted?
Running servers yourself means sandboxing local processes, validating redirect URIs and handling consent, and that's ongoing work whichever package you pick. A hosted gateway moves the server process to someone else, but you still own the credentials and the clients you connect. One thing to look for is deny-by-default tool scoping. A gateway that turns everything on just moves the over-broad-scope problem.
What MCPifex does by default
With MCPifex, write and destructive tools start off. The tools a client sees are filtered to what you enable, and calls to anything else are refused. A tool outside the catalog for that server is always refused. Each session runs in its own isolated process, and every call is logged.
API keys (mcpx_...) work as a Bearer header, or as the first URL path segment for clients that can't send headers, such as a ChatGPT connector. That second form is a product API key, not the spec's OAuth flow, so treat the URL like a password.
Revoking a key stops new calls within about a minute and cuts off an open session on its next call. Saved credentials are encrypted in transit and masked in the UI.
MCPifex's gateway uses the handshake-based MCP transport. Clients on the current revision interoperate through the spec's backward-compatibility rules.
Sources
- MCP Security Best Practices, modelcontextprotocol.io
- MCP Authorization, modelcontextprotocol.io
- MCP 2026-07-28 changelog, modelcontextprotocol.io
- OWASP MCP Top 10 (community beta)
- MCP Tool Poisoning, OWASP
- Tool Poisoning Attacks, Invariant Labs
Ready to connect?
Host any MCP server behind one endpoint and control exactly what your agents can reach.