MCP security checklist: prompt injection, SSRF, least privilege and more
MCP makes it easy to hand an AI app some powerful tools. It also makes it easy to hand over too much. Run through this list before you put any MCP server in front of real users.
This is our own guidance. The protocol facts come from the MCP 2026-07-28 spec. No checklist makes a system "secure". You still need to review your own setup.
The threats, in one table
| Threat | How it happens | What to do about it |
|---|---|---|
| Prompt injection | A tool returns text (web page, ticket, document) with instructions the model follows | Treat tool output as untrusted data. Limit what tools can do. Ask for approval on risky actions |
| Over-privileged tools | One credential can read or change everything | Least privilege, per-user scopes, read-only by default |
| Raw command, SQL or URL tools | A tool accepts a free-form shell string, SQL or URL | Don't build them. Use fixed, parameterised operations |
| SSRF | A fetch tool gets steered to internal addresses | Allow-list hosts, block private ranges, no redirects across hosts |
| Credential leaks | Secrets in the app, logs or responses | Use a secret manager. Never put keys in client code. Redact logs |
| Confused deputy | The server uses its own broad credential for a low-privilege user | Check permissions per user, per call |
| Resource exhaustion | Huge inputs, loops, unbounded output | Size limits, timeouts, rate limits, capped pagination |
| Supply chain | A buggy or malicious dependency | Pin versions, use lockfiles, read release notes, scan dependencies |
Read-only first, approval for anything with consequences
Think of two kinds of tool. Read tools change nothing. Write tools are switched off by default, tightly scoped, and the host must show the user the exact parameters and get a clear yes before the call goes through.
Authentication and authorisation
- Authorization is optional in MCP. For HTTP transports, implementations should follow the MCP authorization spec.
- With stdio, skip the OAuth dance and read credentials from the environment.
- An endpoint reachable over the network is never anonymous. Authorise per user and per tool.
- Check that a token was issued for your server (the audience), not merely that it's well-formed.
Prompt injection: five habits
- Keep data and instructions apart in the host.
- Shrink the blast radius. A model reading an untrusted document shouldn't also hold a tool that can send data out or change records, not in the same step.
- Show a human the parameters before any consequential action.
- Cap the size. Trim, truncate, paginate.
- Test it. Put an injection string in your test data and check that nothing changes.
SSRF and databases
Never take a raw URL from the model. Take an identifier and map it to a fixed, allow-listed endpoint. For databases, don't offer "run any SQL". Offer a fixed catalogue of parameterised queries that run under a read-only account on specific views, with a row cap and a statement timeout.
Day-to-day operations
- Rate-limit per user and per tool. Time out every outbound call.
- Retry only safe reads, with backoff. Never auto-retry a write.
- Keep an audit log: who called what, with redacted arguments, and what happened.
- Pin and scan dependencies. Read release notes before you upgrade.
Privacy
This list does not cover Indian data-protection law. Before you handle personal data of people in India, read the Digital Personal Data Protection Act, 2023 and its rules, and talk to a qualified lawyer.
Related reading
What is MCP? · Build a Python MCP server · The MCP Builder's Handbook has a full security chapter and a production checklist.
Frequently asked questions
Does MCP include authentication?
Authorization is optional in the MCP spec. For HTTP transports, implementations should follow the MCP authorization spec, which builds on OAuth 2.1 (draft) and related RFCs. For stdio they should read credentials from the environment. A remote MCP endpoint must never be anonymous.
What is prompt injection in MCP?
It's when text returned by a tool (a web page, a ticket, an email, a document) contains instructions that the model then follows. Treat anything that came from outside your control as untrusted data.
Should an MCP tool run raw SQL or shell commands?
No. Unrestricted shell, arbitrary SQL and arbitrary URL fetching are not safe defaults. Use fixed, parameterised operations instead.