Skip to content

Commit 5360978

Browse files
authored
Merge branch 'main' into add-chorus-client
2 parents 3fffefb + 78283c8 commit 5360978

File tree

2 files changed

+137
-6
lines changed

2 files changed

+137
-6
lines changed

docs/specification/draft/basic/authorization.mdx

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,19 +178,58 @@ sequenceDiagram
178178
A->>C: Client Credentials
179179
end
180180
181-
Note over C: Generate PKCE parameters
182-
C->>B: Open browser with authorization URL + code_challenge
183-
B->>A: Authorization request
181+
Note over C: Generate PKCE parameters<br/>Include resource parameter
182+
C->>B: Open browser with authorization URL + code_challenge + resource
183+
B->>A: Authorization request with resource parameter
184184
Note over A: User authorizes
185185
A->>B: Redirect to callback with authorization code
186186
B->>C: Authorization code callback
187-
C->>A: Token request + code_verifier
187+
C->>A: Token request + code_verifier + resource
188188
A->>C: Access token (+ refresh token)
189189
C->>M: MCP request with access token
190190
M-->>C: MCP response
191191
Note over C,M: MCP communication continues with valid token
192192
```
193193

194+
#### Resource Parameter Implementation
195+
196+
MCP clients **MUST** implement Resource Indicators for OAuth 2.0 as defined in [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html)
197+
to explicitly specify the target resource for which the token is being requested. The `resource` parameter:
198+
199+
1. **MUST** be included in both authorization requests and token requests.
200+
2. **MUST** identify the MCP server that the client intends to use the token with.
201+
3. **MUST** use the canonical URI of the MCP server as defined in [RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#name-access-token-request).
202+
203+
##### Canonical Server URI
204+
205+
For the purposes of this specification, the canonical URI of an MCP server is defined as the resource identifier as specified in
206+
[RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#section-2) and aligns with the `resource` parameter in
207+
[RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728).
208+
209+
MCP clients **SHOULD** provide the most specific URI that they can for the MCP server they intend to access, following the guidance in [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707). While the canonical form uses lowercase scheme and host components, implementations **SHOULD** accept uppercase scheme and host components for robustness and interoperability.
210+
211+
Examples of valid canonical URIs:
212+
213+
- `https://mcp.example.com/mcp`
214+
- `https://mcp.example.com`
215+
- `https://mcp.example.com:8443`
216+
- `https://mcp.example.com/server/mcp` (when path component is necessary to identify individual MCP server)
217+
218+
Examples of invalid canonical URIs:
219+
220+
- `mcp.example.com` (missing scheme)
221+
- `https://mcp.example.com#fragment` (contains fragment)
222+
223+
> **Note:** While both `https://mcp.example.com/` (with trailing slash) and `https://mcp.example.com` (without trailing slash) are technically valid absolute URIs according to [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986), implementations **SHOULD** consistently use the form without the trailing slash for better interoperability unless the trailing slash is semantically significant for the specific resource.
224+
225+
For example, if accessing an MCP server at `https://mcp.example.com`, the authorization request would include:
226+
227+
```
228+
&resource=https%3A%2F%2Fmcp.example.com
229+
```
230+
231+
MCP clients **MUST** send this parameter regardless of whether authorization servers support it.
232+
194233
### Access Token Usage
195234

196235
#### Token Requirements
@@ -223,6 +262,8 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
223262

224263
MCP servers, acting in their role as an OAuth 2.1 resource server, **MUST** validate access tokens as described in
225264
[OAuth 2.1 Section 5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.2).
265+
MCP servers **MUST** validate that access tokens were issued specifically for them as the intended audience,
266+
according to [RFC 8707 Section 2](https://www.rfc-editor.org/rfc/rfc8707.html#section-2).
226267
If validation fails, servers **MUST** respond according to
227268
[OAuth 2.1 Section 5.3](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.3)
228269
error handling requirements. Invalid or expired tokens **MUST** receive a HTTP 401
@@ -313,8 +354,11 @@ MCP servers **MUST** validate access tokens before processing the request, ensur
313354

314355
A MCP server **MUST** follow the guidelines in [OAuth 2.1 - Section 5.2](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-12.html#section-5.2) to validate inbound tokens.
315356

316-
MCP servers **MUST** only accept tokens specifically intended for themselves.
357+
MCP servers **MUST** only accept tokens specifically intended for themselves and **MUST** reject tokens that do not include them in the audience claim or otherwise verify that they are the intended recipient of the token. See [Security Best Practices Section 2.2](/specification/draft/basic/security_best_practices#token-passthrough) for details.
317358

318359
If the MCP server makes requests to upstream APIs, it may act as an OAuth client to them. The access token used at the upstream API is a seperate token, issued by the upstream authorization server. The MCP server **MUST NOT** pass through the token it received from the MCP client.
319360

320-
If the authorization server supports the `resource` parameter, it is recommended that implementers follow [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) to prevent token misuse.
361+
MCP clients **MUST** implement and use the `resource` parameter as defined in [RFC 8707 - Resource Indicators for OAuth 2.0](https://www.rfc-editor.org/rfc/rfc8707.html)
362+
to explicitly specify the target resource for which the token is being requested. This requirement aligns with the recommendation in
363+
[RFC 9728 Section 7.4](https://datatracker.ietf.org/doc/html/rfc9728#section-7.4). This ensures that access tokens are bound to their intended resources and
364+
cannot be misused across different services.

docs/specification/draft/basic/security_best_practices.mdx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,90 @@ Token passthrough is explicitly forbidden in the [authorization specification](/
141141
#### Mitigation
142142

143143
MCP servers **MUST NOT** accept any tokens that were not explicitly issued for the MCP server.
144+
145+
### 2.3 Session Hijacking
146+
147+
Session hijacking is an attack vector where a client is provided a session ID by the server, and an unauthorized party is able to obtain and use that same session ID to impersonate the original client and perform unauthorized actions on their behalf.
148+
149+
#### 2.3.1 Session Hijack Prompt Injection
150+
151+
```mermaid
152+
sequenceDiagram
153+
participant Client
154+
participant ServerA
155+
participant Queue
156+
participant ServerB
157+
participant Attacker
158+
159+
Client->>ServerA: Initialize (connect to streamable HTTP server)
160+
ServerA-->>Client: Respond with session ID
161+
162+
Attacker->>ServerB: Access/guess session ID
163+
Note right of Attacker: Attacker knows/guesses session ID
164+
165+
Attacker->>ServerB: Trigger event (malicious payload, using session ID)
166+
ServerB->>Queue: Enqueue event (keyed by session ID)
167+
168+
ServerA->>Queue: Poll for events (using session ID)
169+
Queue-->>ServerA: Event data (malicious payload)
170+
171+
ServerA-->>Client: Async response (malicious payload)
172+
Client->>Client: Acts based on malicious payload
173+
```
174+
175+
#### 2.3.2 Session Hijack Impersonation
176+
177+
```mermaid
178+
sequenceDiagram
179+
participant Client
180+
participant Server
181+
participant Attacker
182+
183+
Client->>Server: Initialize (login/authenticate)
184+
Server-->>Client: Respond with session ID (persistent session created)
185+
186+
Attacker->>Server: Access/guess session ID
187+
Note right of Attacker: Attacker knows/guesses session ID
188+
189+
Attacker->>Server: Make API call (using session ID, no re-auth)
190+
Server-->>Attacker: Respond as if Attacker is Client (session hijack)
191+
```
192+
193+
#### 2.3.3 Attack Description
194+
195+
When you have multiple stateful HTTP servers that handle MCP requests, the following attack vectors are possible:
196+
197+
**Session Hijack Prompt Injection**
198+
199+
1. The client connects to **Server A** and receives a session ID.
200+
1. The attacker obtains an existing session ID and sends a malicious event to **Server B** with said session ID.
201+
202+
- When a server supports [redelivery/resumable streams](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#resumability-and-redelivery), deliberately terminating the request before receiving the response could lead to it being resumed by the original client via the GET request for server sent events.
203+
- If a particular server initiates server sent events as a consequence of a tool call such as a `notifications/tools/list_changed`, where it is possible to affect the tools that are offered by the server, a client could end up with tools that they were not aware were enabled.
204+
205+
1. **Server B** enqueues the event (associated with session ID) into a shared queue.
206+
1. **Server A** polls the queue for events using the session ID and retrieves the malicious payload.
207+
1. **Server A** sends the malicious payload to the client as an asynchronous or resumed response.
208+
1. The client receives and acts on the malicious payload, leading to potential compromise.
209+
210+
**Session Hijack Impersonation**
211+
212+
1. The MCP client authenticates with the MCP server, creating a persistent session ID.
213+
2. The attacker obtains the session ID.
214+
3. The attacker makes calls to the MCP server using the session ID.
215+
4. MCP server does not check for additional authorization and treats the attacker as a legitimate user, allowing unauthorized access or actions.
216+
217+
#### 2.3.4 Mitigation
218+
219+
To prevent session hijacking and event injection attacks, the following mitigations should be implemented:
220+
221+
MCP servers that implement authorization **MUST** verify all inbound requests.
222+
MCP Servers **MUST NOT** use sessions for authentication.
223+
224+
MCP servers **MUST** use secure, non-deterministic session IDs.
225+
Generated session IDs (e.g., UUIDs) **SHOULD** use secure random number generators. Avoid predictable or sequential session identifiers that could be guessed by an attacker. Rotating or expiring session IDs can also reduce the risk.
226+
227+
MCP servers **SHOULD** bind session IDs to user-specific information.
228+
When storing or transmitting session-related data (e.g., in a queue), combine the session ID with information unique to the authorized user, such as their internal user ID. Use a key format like `<user_id>:<session_id>`. This ensures that even if an attacker guesses a session ID, they cannot impersonate another user as the user ID is derived from the user token and not provided by the client.
229+
230+
MCP servers can optionally leverage additional unique identifiers.

0 commit comments

Comments
 (0)