MCP TypeScript SDK: OAuthクライアントが、MCPサーバーによって選択された認証サーバーに認証情報を送信する可能性
### 概要
影響を受けるバージョンでは、SDKのOAuthクライアントが、MCPサーバーがどの認証サーバーにクライアントのOAuth認証情報を送信するかを決定できるようにしていました。認証情報は、それが属する認証サーバーに紐付けられていませんでした。
悪意のある、または侵害されたMCPサーバーは、独自の認証サーバーを指定することができました。ユーザーの操作なしに、クライアントは以下を送信します。
- 以前のサインイン時に保存された`refresh_token`と`client_secret`
- バンドルされたプロバイダーで構成された`client_secret`または署名されたアサーション
### 影響はありますか?
以下の両方の条件に当てはまる場合は、影響を受ける可能性があります。
- あなたのアプリケーションが、以下のいずれかの方法でSDKのOAuthクライアントをHTTP経由で使用している場合:
- トランスポート上の`authProvider`
- `withOAuth()`ミドルウェア
- `auth()`または`fetchToken()`への直接的な呼び出し
- 認証情報を保持しながら、完全に信頼できないMCPサーバーに接続する可能性がある
影響を受けるバージョン:
- `@modelcontextprotocol/sdk` 1.12.0から1.30.1
- `@modelcontextprotocol/client` 2.0.0から2.1.0(ただし、以下の条件に該当する場合のみ):
- `expectedIssuer`のないバンドルされたプロバイダー
- `issuer`なしで保存または提供された認証情報
- `fetchToken()`への直接的な呼び出し
- `OAuthTokensSchema`または`OAuthClientInformationSchema`を介してストレージを読み取るプロバイダー
影響を受けないもの:
- SDKで構築されたMCPサーバー
- stdioクライアント
### 修正方法
以下のバージョンにアップグレードしてください。
- 1.x: `@modelcontextprotocol/sdk` 1.31.0以降
- 2.x: `@modelcontextprotocol/client` 2.2.0以降、および直接インポートする場合は`@modelcontextprotocol/core` 2.2.0以降
クライアントは、保存された認証情報に認証サーバーを`issuer`として記録し、異なる認証サーバーに送信しないようになりました。ユーザーが再度サインインするか、エラーが発生します。
以下の場合は、パッチバージョンのアップグレードだけでは不十分です。変更も必要です。
- **バンドルされたプロバイダー** (`ClientCredentialsProvider`, `PrivateKeyJwtProvider`, `StaticPrivateKeyJwtProvider`, `CrossAppAccessProvider`): `expectedIssuer` を指定してください。例えば、`expectedIssuer: 'https://auth.example.com'` のように設定します。指定しない場合、MCPサーバーが指定する認証サーバーが使用されます。
- **`issuer` なしで保存された認証情報:** `OAuthClientProvider` が永続化(ファイル、キーチェーン、データベース)したトークンとクライアント情報は、アップグレード前に保存されたものも含まれます。これには、1.x で 1.31.0 より前に保存されたすべての情報が含まれます。これらは、最初に利用する際に指定された認証サーバーにアクセスします。これらの認証情報に `issuer` を追加するか、削除して、ユーザーに再度サインインさせる必要があります。
- **独自の `OAuthClientProvider`:** `saveTokens()` および `saveClientInformation()` に渡される情報を正確に保存してください。これには `issuer` も含まれます。事前に登録された認証情報の場合、`clientInformation()` が返す情報に `issuer` を含めてください。
この修正に含まれないもの:
- 新しいインタラクティブなサインイン機能は、引き続き MCPサーバーが指定する認証サーバーにアクセスします。信頼できるサーバーでのみ、完全なサインインを行ってください。
- `refreshAuthorization()` および `exchangeAuthorization()` を直接呼び出す場合。
- `skipIssuerMetadataValidation: true` が設定された 2.x の場合。
影響を受けたクライアントが、信頼できない MCP サーバーに接続していた可能性がある場合、クライアントシークレットまたは署名キーをローテーションし、トークンを無効にしてください。
まだアップグレードできない場合は、OAuthクライアントを信頼できる MCP サーバーにのみ接続してください。2.0.0 および 2.1.0 は、すでに `expectedIssuer` をサポートしています。
影響を受けるパッケージ:
- npm (JavaScript) @modelcontextprotocol/sdk: 影響範囲は 1.12.0 以上、1.31.0 未満。1.31.0 で修正済み。
- npm (JavaScript) @modelcontextprotocol/client: 影響範囲は 2.0.0 以上、2.2.0 未満。2.2.0 で修正済み。