Someone on your platform team wired an AI agent into Microsoft Graph last month. It runs as an MCP server with a client secret in an environment variable, and nobody has asked who else can talk to it.
MCP server security is an identity problem now. Whatever credential sits behind an MCP server, the AI agent can use. So can anyone who reaches the server, and anyone who can slip instructions into what the agent reads. In 2026 attackers and researchers showed exactly how that goes wrong.
What is MCP?
The Model Context Protocol is an open standard that lets AI clients like Claude, Copilot or Cursor discover and call "tools" on a server: read a mailbox, query a database, open a ticket. The model reads each tool's description and decides what to call with which arguments. The server runs the call with its own credentials, so that's where the risk lives.
What happened in 2026
- Both official SDKs could hand OAuth credentials to a malicious server. In late September the TypeScript and Python SDKs published High-severity advisories: a hostile server could name its own authorization server and collect the client's stored secrets or tokens. On October 5 another TypeScript advisory showed server bearer auth accepting tokens issued for other services. In many setups, upgrading alone doesn't fix it; you also have to turn on the new issuer or audience checks.
- Researchers verified bugs in 343 tools across 118 servers. The ToFu paper (October 9) fuzzed 3,405 tools on 273 MCP servers and found that tools often don't enforce their own documented input rules.
- Exposed servers answer strangers. In July, Wiz Research reported that about 70% of the internet-exposed MCP servers it probed listed their tools to an anonymous caller, and about 42% returned real data.
- MCP turned up in a ransomware intrusion. CloudSEK reported a Gentlemen ransomware affiliate who connected an AI coding assistant to a reverse-shell handler over MCP to run commands on victim machines (Infosecurity Magazine). The way in was stolen CI/CD secrets, not an MCP bug.
MCP vulnerabilities: six attack classes
- Tool poisoning. Hidden instructions in a tool description that the model follows and the user never sees. Invariant Labs showed an innocent
addtool telling the model to read SSH keys. Tool results work the same way: one email the agent summarizes can carry a prompt injection. - Rug pulls and supply chain. A server can change its tool descriptions after you approved it, and a community package can turn malicious in an update. Classic supply chain attack, with a model in the middle.
- Unauthenticated exposure. Servers listening on every interface with no auth at all.
- Argument injection. Path traversal in file tools, SSRF in fetch tools, SQL injection in query tools. The model writes the input, and the model can be talked into anything.
- OAuth confusion. Token passthrough, missing audience checks, confused deputy proxies. The MCP security best practices say servers MUST NOT accept tokens that weren't issued for them. More in OAuth 2.0 flaws.
- Over-privileged credentials. The server holds a secret with far more access than any tool needs.
The Microsoft 365 and Entra ID angle
An MCP server that calls Microsoft Graph is a service principal with a new front door. Anything that steers the agent inherits its permissions. A Graph app with application Mail.Read reads every mailbox in the tenant, and that exfiltration path never touches a user sign-in or an MFA prompt. We covered the identity side in AI agent identities and service principal sprawl.
What helps:
- Shrink the blast radius at the API. Scope mail access to named mailboxes with RBAC for Applications in Exchange Online, and use
Sites.Selectedinstead ofSites.Read.All. Prefer delegated permissions when a person is in the loop. - Restrict user consent so a new AI connector needs admin approval.
- Watch workload identity sign-ins. App-only tokens land in the service principal sign-in logs, the same blind spot as non-interactive sign-ins. Graph activity logs show what each app called.
- Add Conditional Access for workload identities. It blocks a single-tenant service principal outside known IP ranges or when flagged risky. It needs Workload Identities Premium and doesn't cover multitenant apps or managed identities (Microsoft Learn).
Start with this query and look for apps or IPs you can't explain:
AADServicePrincipalSignInLogs
| where TimeGenerated > ago(14d)
| summarize SignIns = count(), IPs = make_set(IPAddress, 20) by ServicePrincipalName, AppId
| order by SignIns desc
MCP security checklist
Copy it into your ticket system, one copy per server.
Inventory
- List every MCP server in use: remote ones, and local ones developers added to IDE and agent config files.
- Record an owner, the credential type and the data each server reaches.
- Pin server versions and review tool description changes on every update.
Authentication
- No remote MCP server without authentication. Local servers use stdio, or bind to localhost with a token.
- Upgrade the SDKs past the September and October 2026 advisories, then set the issuer and audience options they describe.
- If a client may have connected to an untrusted server, rotate its secrets and revoke its tokens.
Authorization and scopes
- One service principal per server, least privilege, no
.Allapplication permission without a written reason. - Split read tools from write tools, with separate credentials where you can.
Input validation
- Treat every tool argument as attacker input: confine file paths to an allowed root, parameterize SQL, allowlist URLs.
- Treat tool results as untrusted data, never as instructions.
Egress
- Let the server reach only the APIs it needs. Block cloud metadata endpoints and private ranges from fetch tools.
Logging
- Log every tool call with caller, tool name, redacted arguments and result size.
- Send service principal sign-ins and Graph activity logs to your SIEM and alert on new source IPs.
Human approval
- Require approval for destructive or outbound actions: sending mail, deleting, sharing, running commands.
- Don't run auto-approve modes on agents that hold production credentials.
The one thing to do this week
Pick the MCP server that holds a Graph credential and answer two questions: what can that secret read, and who can reach the server? If either answer surprises you, start there. If you want a second pair of eyes on which service principals hold tenant-wide permissions, SecValley's read-only Entra ID and Microsoft 365 scan lists them with credential expiry and owner state.
Frequently Asked Questions
What is MCP server security?
The controls that stop an MCP server from being misused: authentication on every remote server, least-privilege credentials, validated tool arguments, limited egress, logged tool calls and human approval for risky actions.
What is MCP tool poisoning?
A prompt injection hidden in a tool's description or output. The model follows it, for example by reading secrets and sending them out, while the user sees a normal tool call.
Does OAuth make an MCP server secure?
Only when it is checked properly. Servers must reject tokens issued for other services and never pass client tokens downstream, and clients must verify which authorization server receives their credentials.
How do I secure an MCP server that uses Microsoft Graph?
Treat it as a service principal: narrowest Graph permissions, scoped mailbox and SharePoint access, restricted user consent, monitored service principal sign-ins, and Conditional Access for workload identities where licensed.