Skip to content

Commit b7909f9

Browse files
authored
Merge pull request modelcontextprotocol#407 from modelcontextprotocol/pcarleton/confused-deputy
[spec] Auth: Confused deputy
2 parents c8567fb + e7f2c58 commit b7909f9

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

docs/specification/draft/basic/authorization.mdx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,16 @@ MCP clients **MUST** have redirect URIs registered with the authorization server
293293

294294
Authorization servers **MUST** validate exact redirect URIs against pre-registered values to prevent redirection attacks.
295295

296+
MCP clients **SHOULD** use and verify state parameters in the authorization code flow
297+
and discard any results that do not include or have a mis-match with the original state.
298+
296299
Authorization servers **MUST** take precautions to prevent redirecting user agents to untrusted URI's, following suggestions laid out in [OAuth 2.1, Section 7.12.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-7.12.2)
300+
301+
Authorization servers **SHOULD** only automatically redirect the user agent if it trusts the redirection URI. If the URI is not trusted, the authorization server MAY inform the user and rely on the user to make the correct decision.
302+
303+
### 3.4 Confused Deputy Problem
304+
305+
Attackers can exploit MCP servers acting as intermediaries to third-party APIs, leading to confused deputy vulnerabilities. By using stolen authorization codes, they can obtain access tokens without user consent. See [Security Best Practices 2.1](/specification/draft/basic/security_best_practices) for details.
306+
307+
MCP proxy servers using static client IDs **MUST** obtain user consent for each dynamically
308+
registered client before forwarding to third-party authorization servers (which may require additional consent).
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
title: Security Best Practices
3+
---
4+
5+
## 1. Introduction
6+
7+
### 1.1 Purpose and Scope
8+
9+
This document provides security considerations for the Model Context Protocol (MCP), complementing the MCP Authorization specification. This document identifies security risks, attack vectors, and best practices specific to MCP implementations.
10+
11+
The primary audience for this document includes developers implementing MCP authorization flows, MCP server operators, and security professionals evaluating MCP-based systems. This document should be read alongside the MCP Authorization specification and [OAuth 2.0 security best practices](https://datatracker.ietf.org/doc/html/rfc9700).
12+
13+
## 2. Attacks and Mitigations
14+
15+
This section gives a detailed description of attacks on MCP implementations, along with potential countermeasures.
16+
17+
### 2.1 Confused Deputy Problem
18+
19+
Attackers can exploit MCP servers proxying other resource servers, creating "[confused deputy](https://en.wikipedia.org/wiki/Confused_deputy_problem)" vulnerabilities.
20+
21+
#### 2.1.1 Terminology
22+
23+
**MCP Proxy Server**
24+
: An MCP server that connects MCP clients to third-party APIs, offering MCP features while delegating operations and acting as a single OAuth client to the third-party API server.
25+
26+
**Third-Party Authorization Server**
27+
: Authorization server that protects the third-party API. It may lack dynamic client registration support, requiring MCP proxy to use a static client ID for all requests.
28+
29+
**Third-Party API**
30+
: The protected resource server that provides the actual API functionality. Access to this
31+
API requires tokens issued by the third-party authorization server.
32+
33+
**Static Client ID**
34+
: A fixed OAuth 2.0 client identifier used by the MCP proxy server when communicating with
35+
the third-party authorization server. This Client ID refers to the MCP server acting as a client
36+
to the Third-Party API. It is the same value for all MCP server to Third-Party API interactions regardless of
37+
which MCP client initiated the request.
38+
39+
#### 2.1.2 Architecture and Attack Flows
40+
41+
##### 2.1.2.1 Normal OAuth proxy usage (preserves user consent)
42+
43+
```mermaid
44+
sequenceDiagram
45+
participant UA as User-Agent (Browser)
46+
participant MC as MCP Client
47+
participant M as MCP Proxy Server
48+
participant TAS as Third-Party Authorization Server
49+
50+
Note over UA,M: Initial Auth flow completed
51+
52+
Note over UA,TAS: Step 1: Legitimate user consent for Third Party Server
53+
54+
M->>UA: Redirect to third party authorization server
55+
UA->>TAS: Authorization request (client_id: mcp-proxy)
56+
TAS->>UA: Authorization consent screen
57+
Note over UA: Review consent screen
58+
UA->>TAS: Approve
59+
TAS->>UA: Set consent cookie for client ID: mcp-proxy
60+
TAS->>UA: 3P Authorization code + redirect to mcp-proxy-server.com
61+
UA->>M: 3P Authorization code
62+
Note over M,TAS: Exchange 3P code for 3P token
63+
Note over M: Generate MCP authorization code
64+
M->>UA: Redirect to MCP Client with MCP authorization code
65+
66+
Note over M,UA: Exchange code for token, etc.
67+
```
68+
69+
##### 2.1.2.3 Malicious OAuth proxy usage (skips user consent)
70+
71+
```mermaid
72+
sequenceDiagram
73+
participant UA as User-Agent (Browser)
74+
participant M as MCP Proxy Server
75+
participant TAS as Third-Party Authorization Server
76+
participant A as Attacker
77+
78+
79+
Note over UA,A: Step 2: Attack (leveraging existing cookie, skipping consent)
80+
A->>M: Dynamically register malicious client, redirect_uri: attacker.com
81+
A->>UA: Sends malicious link
82+
UA->>TAS: Authorization request (client_id: mcp-proxy) + consent cookie
83+
rect rgba(255, 17, 0, 0.67)
84+
TAS->>TAS: Cookie present, consent skipped
85+
end
86+
87+
TAS->>UA: 3P Authorization code + redirect to mcp-proxy-server.com
88+
UA->>M: 3P Authorization code
89+
Note over M,TAS: Exchange 3P code for 3P token
90+
Note over M: Generate MCP authorization code
91+
M->>UA: Redirect to attacker.com with MCP Authorization code
92+
UA->>A: MCP Authorization code delivered to attacker.com
93+
Note over M,A: Attacker exchanges MCP code for MCP token
94+
A->>M: Attacker impersonates user to MCP server
95+
```
96+
97+
#### 2.1.3 Attack Description
98+
99+
When an MCP proxy server uses a static client ID to authenticate with a third-party
100+
authorization server that does not support dynamic client registration, the following
101+
attack becomes possible:
102+
103+
1. A user authenticates normally through the MCP proxy server to access the third-party API
104+
2. During this flow, the third-party authorization server sets a cookie on the user agent
105+
indicating consent for the static client ID
106+
3. An attacker later sends the user a malicious link containing a crafted authorization request which contains a malicious redirect URI along with a new dynamically registered client ID
107+
4. When the user clicks the link, their browser still has the consent cookie from the previous legitimate request
108+
5. The third-party authorization server detects the cookie and skips the consent screen
109+
6. The MCP authorization code is redirected to the attacker's server (specified in the crafted redirect_uri during dynamic client registration)
110+
7. The attacker exchanges the stolen authorization code for access tokens for the MCP server without the user's explicit approval
111+
8. Attacker now has access to the third-party API as the compromised user
112+
113+
#### 2.1.4 Mitigation
114+
115+
MCP proxy servers using static client IDs **MUST** obtain user consent for each dynamically
116+
registered client before forwarding to third-party authorization servers (which may require additional consent).

0 commit comments

Comments
 (0)