Skip to content
All posts

The MCP Security Reckoning: 10 SDK Advisories in 8 Days

Devdatta Narawade8 min read

In the eight days between 28 September and 5 October 2026, the Model Context Protocol project published ten security advisories for its official SDKs — six for Python, four for TypeScript. That is not ten CVEs in ten niche libraries. It is ten flaws in the shared substrate under most of the MCP clients and servers your agent already talks to, and at least two of the fixes do nothing until you switch them on yourself.

Here is what the advisories actually say, which three matter enough to patch today, and the hardening steps that turn an upgrade into an actual mitigation.

What happened in the MCP SDKs in 2026?

Between 28 September and 5 October 2026, the official Model Context Protocol SDKs published ten security advisories — six Python (mcp) and four TypeScript (@modelcontextprotocol/*). They cluster around one theme: the SDK trusted the wrong party. Tokens were accepted for the wrong server, credentials were sent to a server-chosen endpoint, and sessions were bound to an ID rather than a principal. Because a large share of MCP clients and servers are built on these libraries, a flaw in the SDK is a flaw in everything above it.

The OAuth flaws, in one breath

Three of the ten are variations on missing audience and issuer validation. The SDK client did not always verify that the authorization server named by an MCP server was the one its credentials belonged to; the server did not always check that a token was issued for it; and one legacy discovery path skipped issuer validation entirely. Each is a way for a malicious or merely compromised MCP server to obtain or replay credentials it should never see.

Why the fixes are inert until you enable them

This is the part people miss. The Python server-side patch that closes the audience gap adds a validate_token_resource setting that is off by default. Upgrading the package changes nothing on its own: you must set validate_token_resource=True and point resource_server_url at the audience your authorization server actually mints. Two of the ten fixes in the batch work the same way — patched, but dormant until configured. An upgrade without the setting is a false sense of safety.

The three advisories that matter most

# Where What breaks Fixed in
1 Python server (GHSA-w4fh-qvv9-3v23) Your server accepts a token issued for a different resource server mcp 1.30.0 / 2.2.0 — opt-in
2 TypeScript client (GHSA-6qxp-vccf-f47h) Client sends refresh_token / client_secret to an authorization server the MCP server chose @modelcontextprotocol/sdk 1.31.0 / client 2.2.0
3 Python transports (GHSA-jpw9-pfvf-9f58) Any request with a known session ID is served, regardless of who authenticated mcp 1.27.2

#1 — the server accepts a token that was not meant for it

Where one authorization server issues tokens for several services, the Python SDK's server-side bearer authentication had no way to check the token's audience. A valid token for another service was accepted by your MCP server. The patch adds validate_token_resource — and leaves it off, because defaulting it on would lock out every server that has not set resource_server_url. That is a defensible choice for the maintainers and a foot-gun for you: the mitigation is one line you have to remember to write.

#2 — the client sends credentials to whoever the server names

The TypeScript OAuth client let the MCP server dictate which authorization server received the client's credentials, because the stored credentials were not bound to the authorization server they belonged to. A malicious server could name its own authorization server and receive the stored refresh_token and client_secret with no user interaction. If you use the OAuth client over HTTP — an authProvider on a transport, the withOAuth() middleware, or direct auth()/fetchToken() calls — and you might connect to a server you do not fully trust, you were exposed. The fix binds credentials to an expected issuer; in the 2.x client the vulnerable subset is narrower, covering bundled providers with no expectedIssuer and calls that store or supply credentials without an issuer.

#3 — sessions bound to an ID, not a principal

The June filing predates the batch but belongs with it. The Python SSE and Streamable HTTP transports routed requests into an existing session using only the session ID, never comparing the request's authentication context to the one that created the session. Anyone who learned or guessed a session ID could inject JSON-RPC messages into that session while carrying a bearer token of their own. Patched in 1.27.2. Only HTTP transports with authentication configured are affected; stdio and stateless HTTP are not.

The bigger picture: MCP is where prompt injection lands

The SDK advisories are the plumbing half of a two-part story. The other half is that agentic coding assistants have crossed from autocomplete into high-privilege agents that read files, run shell commands, and reach the network — and that privilege is remotely hijackable. We covered why prompt injection is now #1 in the OWASP GenAI Top Ten, and the underlying research is blunt: a 2026 systematization of 78 studies catalogues 42 techniques and reports attack success rates against state-of-the-art defenses above 85% under adaptive attacks.

Tool invocation is the seam

An ISSTA 2026 red-team study of six production agents found the exploit concentrates at tool invocation: a "mode gap" where an agent applies less scrutiny to structured tool-call arguments than to ordinary conversation, and where prompt leakage is used as reconnaissance. MCP sits exactly on that seam — it is the tool-invocation protocol. That is why an OAuth bug in the SDK is not a boring crypto footnote but a direct path from a poisoned server to your agent's privileges.

How to harden your MCP client and server

Upgrading is necessary and not sufficient. Do these in order.

If your agent is an MCP client (it connects out to servers)

  • Move to @modelcontextprotocol/sdk 1.31.0 / @modelcontextprotocol/client 2.2.0 or later — the advisory's own patched versions.
  • Bind credentials to an issuer: use bundled providers with expectedIssuer, and store or supply credentials with issuer set.
  • Be deliberate about connecting to servers you do not fully trust while holding OAuth credentials for a legitimate identity provider. That combination is the whole attack.

If your agent hosts an MCP server

  • Move to mcp 1.30.0 / 2.2.0 or later, then enable the audience check: validate_token_resource=True plus resource_server_url set to the correct audience. Without those two lines you upgraded for nothing.
  • Ensure your own token verifier checks aud if you do not adopt the built-in setting.
  • Move to 1.27.2+ for session-to-principal binding on SSE and Streamable HTTP.

Read the advisory, not the roundup

The summaries disagree on the TypeScript safe line — the advisory names 1.31.0, one widely-shared roundup names 1.32.0 — so go to at least the advisory's patched version, and preferably the higher number. One causal write-up of the worst OAuth flaw (a legacy discovery path that fetched configuration from an untrusted server after a 404) is itself labeled AI-generated and not officially reviewed; treat its mechanism as indicative, and the advisory as authoritative. Patch-before-disclosure also matters here: the Python 1.30.0 / 2.2.0 releases were on PyPI from 7 September, so between then and the advisory anyone who had not upgraded was running known-vulnerable code without knowing it.

FAQ

What was the MCP security issue in October 2026?

The official SDKs published ten advisories between 28 September and 5 October 2026 — six Python, four TypeScript — mostly OAuth flaws where credentials or tokens were trusted with the wrong party, plus a session-binding flaw on HTTP transports.

Do I just need to upgrade the MCP SDK?

No. The most important fixes are opt-in: the Python audience validation requires validate_token_resource=True and resource_server_url to be set, or you are patched but still exposed.

Is MCP itself insecure?

MCP is a protocol, and the flaws were in the official SDKs, not the spec. But because most clients and servers are built on those SDKs, an SDK bug behaves like a protocol bug for everyone downstream — which is why the shared substrate deserves share-of-attention.

How does this relate to prompt injection?

MCP is the tool-invocation layer, and tool invocation is the highest-yield surface for indirect prompt injection. A compromised MCP server can be both the injection delivery vector and the credential-theft target.

What should I do first?

Upgrade the SDK, then bind credentials to an issuer on the client and enable audience validation on the server. The upgrade is the part that is easy to do and, by itself, insufficient.

The through-line

Ten advisories in eight days is not a crisis — it is a maturing protocol finding its seams in public, which is the healthy version of this story. What is not healthy is an operator who reads "fixed in 1.30.0", upgrades, and walks away while the flag that closes the hole stays off. Patch, then configure; the second step is the one that stops the attack. If you run an agent with shell and network access, that is the discipline the rest of this month's releases were also circling, and it is worth reading our own security posture against the same checklist.

Related reading