MCP and Agent Security
MCP and OAuth: Securing the Trust Anchor
Securing the OAuth trust anchor in MCP comes down to pinning and validating four things server-side: the authorization server, the origin of the protected resource metadata, the requested scope, and the token's audience. MCP adopted OAuth 2.1 as its authorization layer and inherited a whole class of trust-root errors with it. This class has the highest leverage of all MCP risks, because a single library defect reaches every dependent server.
- Pin or allowlist the origin of the authorization server server-side, instead of taking it from a client-influenced source.
- Honor a
resource_metadatapointer only if its origin matches the resource origin (RFC 9728). - Intersect the requested scope with the client's entitlement, deny by default, never grant it verbatim.
- Validate the token audience (
aud), so a token is only valid at its intended recipient.
Why OAuth in MCP becomes a target
In MCP, OAuth 2.1 governs which client may access a resource server with which rights. The trust anchor is the question of whom the client believes when it learns where to go for authorization. That is exactly where the problem lies: the pointer to the authorization server and the resource metadata often comes from a server-controlled WWW-Authenticate header. If the client or server takes that pointer without pinning origin and issuer, a malicious or interposed resource server can redirect the grant to its own infrastructure, harvest the issued token, or inject an overly broad scope into the consent.
That is what makes this class so delicate: the vulnerable point does not sit in a single server, but in the shared libraries and SDKs underneath. This is why the attack front has moved from individual servers to those libraries. A defect there is inherited by every downstream server, without its operator having made a mistake of their own.
The four checkpoints in detail
1. Pin the authorization server origin
The client must not take the authorization server blindly from a value the resource server influences. The origin of the authorization server belongs pinned server-side or set to a fixed allowlist. If the client instead adopts an arbitrary authorization_server_url, an attacker can redirect the entire token flow to their own infrastructure. That is a classic confused deputy: the client hands over the resource token while trusting an unverified origin.
2. Check the PRM origin against the resource origin (RFC 9728)
RFC 9728 describes how a client finds the protected resource metadata of a resource server. The security rule with it: a resource_metadata pointer is honored only if its origin equals the origin of the resource server. Without this same-origin check, a server can point at foreign metadata and steer the client to a substituted authorization server. The check has to be real origin equality, comparing scheme, host, and port, not a loose prefix check.
3. Intersect the scope with the entitlement
A client should only get the scope it is actually entitled to. If the scope named in the request is adopted verbatim into the consent, an attacker can inject an overly broad scope and obtain rights that go far beyond the use case. The right approach is the intersection: the granted scope is the requested scope intersected with the client's entitlement, deny by default. That limits the damage even when part of the flow was tampered with.
4. Validate the token audience
An access token carries an audience that names the intended recipient. If the aud claim is not validated, a resource server accepts a token that was issued for a different service. Validating the audience makes sure a token captured in one place cannot be reused in another. Together with the intersected scope, that significantly limits an attacker's lateral movement.
Why this class so often escapes reviews
The trust anchor lives between the components, not inside a single one. A review that only reads the server code sees the correct handler and misses that the origin of the authorization pointer was never pinned. What makes it harder is that the actual weakness often sits in a shared library that many servers use in common. Anyone checking only their own repository does not find the bug, even though their own server inherits it. The check only becomes reliable when it looks at the flow across the boundaries and tests each of the four checkpoints against a defined invariant.
Does your OAuth trust anchor hold?
In a free initial call, we check the four checkpoints on your MCP server and name whether the origin of the authorization server and metadata is demonstrably pinned. Every finding comes with a proof of concept, not a guess.
Book a free callCyberSec42 is an independent technical security assessment, not an accredited certification body.
Frequently asked questions
Why does MCP use OAuth at all?
MCP adopted OAuth 2.1 as its authorization layer to govern which client may access a resource server with which rights. But with it, MCP also inherits OAuth's trust-root errors when origin and scope are not pinned and intersected cleanly.
What is the OAuth trust anchor in MCP?
The trust anchor is the question of whom the client believes when it learns where to go for authorization. The pointer to the authorization server and resource metadata often comes from a server-controlled header. If it is adopted unchecked, an attacker can redirect the token flow.
What does RFC 9728 govern for MCP?
RFC 9728 describes how a client finds the protected resource metadata of a resource server. The security rule: a resource_metadata pointer is honored only if its origin equals the origin of the resource server. This same-origin check prevents a server from pointing at foreign metadata.
Why is this the class with the highest leverage?
Because the weakness often sits in the shared libraries and SDKs beneath the servers. A single defect there is inherited by every dependent server, without its operator having made a mistake of their own. This is why the attack front has moved from individual servers to the libraries.
Is validating the audience enough?
No. The audience check is one of four checkpoints. Without a pinned authorization server origin, a same-origin check of the metadata, and an intersected scope, the trust anchor stays exposed. The four invariants work together and should all be enforced.