この記事のポイント
- 脆弱性
- CVE-2026-111770
- 深刻度
HIGH7.7
- 対象
- @modelcontextprotocol/server 2.0.0以上2.3.0未満(HTTPでサーバーまたはステートレス・トランスポートを共有する構成)
- 悪用状況
- 不明
- 推奨対応
- 2.3.0以降へ更新し、MCPサーバーとトランスポートをリクエスト単位またはセッション単位で分離してください。複数クライアントの並行テストとログ確認も実施します。
- 公表日
目次
公式の(MCP)TypeScript Server に、経由で複数のクライアントを受け付ける構成において、あるクライアント向けの応答や通知が別のクライアントへ届く可能性がある-2026-111770が公表されました。対象は@modelcontextprotocol/server 2.0.0以上2.3.0未満で、修正版は2.3.0です。
優先して確認すべきなのは、MCPサーバーをHTTPで公開し、複数利用者または複数エージェントから到達でき、同じMcpServer/Serverインスタンスまたはステートレス・トランスポートを使い回している環境です。更新だけでは処理が止まることがあるため、サーバーとトランスポートをリクエスト単位またはセッション単位で分離する実装変更まで必要です。本稿は2026年10月27日に公式と修正差分を確認したニュース解説です。
スポンサーリンク
影響は「MCPへ接続できること」よりインスタンス共有で決まる
問題の中心は方式やツールの内容ではなく、HTTP接続をまたいで状態を共有する実装です。公式アドバイザリによると、影響する版ではメッセージの接続先を-RPCのidだけで対応付けていました。SDKクライアントは通常0からリクエスト番号を付けるため、別々のクライアントでも同じ番号が現れます。サーバーやトランスポートが共有されていると、その衝突によって応答や通知の送信先を取り違える可能性があります。
これはAIモデルが誤った回答を作る現象ではありません。ツール実行結果、エラー、通知など、MCPの通信そのものが別の接続へ渡り得る問題です。ツールが顧客情報、社内文書、内容、運用ログを返すなら機密性への影響があります。別利用者の結果を自分の処理結果として受け取れば、エージェントが誤った後続操作を選ぶおそれもあります。 v3.1は7.7(High)で、公式評価は機密性High、完全性Low、可用性Highです。
| 確認項目 | 影響判断 |
|---|---|
| パッケージ | @modelcontextprotocol/server 2.0.0〜2.2.0 |
| 接続方式 | 複数クライアントが到達できるHTTP |
| 危険な生成単位 | 起動時に1個作り、全リクエストで同じサーバーまたはステートレス・トランスポートを共有 |
| 影響外と明記 | stdioサーバー、呼び出しごとに新規サーバーを作るcreateMcpHandler()、@modelcontextprotocol/sdk 1.26.0以降 |
@modelcontextprotocol/server 2.3.0以降 |
最初に依存版とHTTP公開範囲を棚卸しする
アプリの直下だけでなく、ワークスペースや共通基盤が間接依存としてSDKを入れている場合もあります。対象リポジトリでを保全した上で、利用するパッケージマネージャーに合わせて依存経路を確認します。
npm ls @modelcontextprotocol/server
npm explain @modelcontextprotocol/server
モノレポではルートだけでなく、実際にMCPサーバーを配備する各ワークスペースで実行してください。コンテナの場合は、ソースのpackage.jsonではなく、配備イメージに入ったロックファイルや、ログでも版を照合します。開発環境を更新しても、古いイメージが稼働していれば対応は完了していません。
次に、HTTPエンドポイントへ誰が到達できるかを確認します。インターネット公開だけが対象ではありません。社内ゲートウェイの背後でも、複数部署、複数、複数エージェントが同じプロセスへ接続するなら、クライアント間の境界があります。反対に、各利用者が自分の端末で起動するstdio構成は公式に影響外とされています。ただし、stdioだから他の脅威もないという意味ではありません。
スポンサーリンク
更新後は「1個を共有する実装」を必ず直す
2.3.0へ更新すると、共有を続ける危険な実装をSDKが拒否します。2回目のconnect()はALREADY_CONNECTEDとなり、ステートレス・トランスポートは2回目のリクエストを拒否します。そのため、パッケージ更新後に疎通確認を1回だけ成功させても不十分です。2件以上の要求を並行または連続で送り、再利用を前提にしていたコードが失敗するかを確かめる必要があります。
公式が示す修正方針は三つです。createMcpHandler()には生成済みオブジェクトではなく、呼び出しごとに新しいMcpServerを作るファクトリーを渡します。低レベルのHTTPハンドラーでは、リクエスト処理の内側でサーバーとトランスポートを作ります。状態を保持する場合はsessionIdGeneratorを設定し、セッションごとにサーバーとトランスポートの組を分離して管理します。
// ステートレスHTTPの考え方
app.post('/mcp', async (req, res) => {
const server = buildMcpServer();
const transport = buildStatelessTransport();
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
上のコードは生成単位を示す概念例であり、そのまま動く完成コードではありません。利用しているexpress、fastify、hono、node向けミドルウェアの現行READMEと型定義に合わせてください。公式の修正では、これらのREADME例も、サーバーをハンドラー外で1回作る形からリクエストごとに作る形へ変更されました。セッション方式では、切断時の破棄、タイムアウト、上限数も設計しないと、古いセッションの残留やメモリ消費という別の問題が生じます。
並行テストで利用者境界を検証する
修正確認では、単独クライアントの正常系だけでなく、クライアントAとBから同時に要求を送り、互いに異なる識別可能なテストデータを返すツールを使います。Aの応答、進捗通知、エラー、キャンセル結果がBへ届かず、その逆も成立することを確認します。JSON-RPCのidは両方で同じ値から始めると、今回の境界を検証しやすくなります。本番の秘密や顧客データはテストに使いません。
- 2クライアントから同じ
idの要求を並行送信する - 通常応答だけでなく通知、エラー、キャンセルも送信先を確認する
- 片方を切断・再接続し、古いセッションへ配送されないことを確認する
- 認証主体、セッションID、接続ID、ツール名、結果の宛先をログで追えるようにする
- ログ本文にはツール結果やトークンをそのまま残さず、相関IDと配送判断を記録する
負荷試験では、更新後にALREADY_CONNECTEDや2回目要求の拒否が増えていないかも確認します。このエラーは修正版が危険な再利用を止めた合図であり、安易な再試行で隠すべきではありません。インスタンスの生成位置を直し、接続単位が意図どおりかを確かめてから再試行戦略を調整します。
スポンサーリンク
漏えいの可能性がある場合は更新と調査を分ける
対象版・共有実装・複数クライアントという条件が揃っていた場合、更新だけで過去の影響は分かりません。まず対象期間、稼働した版、履歴、到達可能だった利用者やエージェントを確定します。次に、同時刻に異なる認証主体で同じJSON-RPC IDが使われた接続、応答先と要求元の主体が一致しない記録、不自然な再接続やキャンセルを調べます。アプリケーションログだけで本文まで残していなければ、混線の有無を完全に復元できない場合があります。その限界も調査記録に残します。
他利用者の秘密や、個人情報を含むツール結果が誤配送された可能性があるなら、データ種別と受信可能だった主体を絞り、必要な資格情報の失効・再発行、利用者通知、法務・個人情報保護担当への連携を判断します。公式アドバイザリは実環境での悪用や漏えい事例を確認したとは述べていません。したがって、影響条件に合うことだけで侵害済みと断定せず、ログと構成から評価します。
完了条件は版・生成単位・境界テストの三つ
対応完了は「2.3.0がロックファイルに入った」だけでは判断できません。配備物が2.3.0以降であること、HTTPのサーバー/トランスポートがリクエストまたはセッションごとに分離されていること、複数クライアントの並行テストで応答・通知・エラーが混ざらないことの三つを記録します。セッション方式なら破棄条件と所有者の対応も確認対象です。
MCPの認証・認可は、誰がどのツールを呼べるかを制御します。今回の脆弱性は、その判定後に返すメッセージの配送境界で起きます。認証を導入済みでも、同じプロセス内の状態分離が崩れれば別利用者へ結果が渡り得ます。基盤では、権限、ツール定義、通信セッションを別々の境界として点検してください。
リバースプロキシやJWTだけでは配送境界を直せない
で利用者ごとに接続を振り分けていても、同じアプリケーションプロセスへ複数接続が入る構成なら、プロセス内の共有は残ります。スティッキーセッションも、ある利用者を同じバックエンドへ送る仕組みであり、バックエンド内のサーバーオブジェクトを利用者ごとに分ける機能ではありません。のsubやtenant_idを検証していても、認証後の応答配送がJSON-RPC IDだけで決まれば今回の問題を防げません。
修正を段階展開する場合は、まずで複数クライアントの同時試験を実施し、次に一部インスタンスへ2.3.0とコード変更を同時に配備します。エラー率、接続数、セッション数、メモリ使用量、処理時間を旧版と比較し、危険な共有がなくても容量不足で失敗していないかを見ます。新しいインスタンスをリクエストごとに作る設計では、ツール登録や外部クライアント生成まで毎回重くしないよう、変更可能な接続状態と読み取り専用の設定を分けてください。ただし、性能対策として状態を再び共有し、脆弱な形へ戻さないことが優先です。
手順も、古いSDKへ戻すだけでは安全になりません。互換性問題で2.3.0を戻す必要がある場合でも、公式が示すリクエスト単位またはセッション単位の生成変更は維持します。変更を維持できないなら、MCPのHTTP入口を単一クライアントへ制限するか停止し、複数利用者へ再公開しない判断が必要です。
関連記事
出典・一次情報
本記事は以下の公開情報をもとに作成しています。最新の状況は各リンク先で確認してください。












![[入門]LLMアプリ開発 --基本・LLMのしくみ・MCP・AIセキュリティ](https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/4707/9784297154707_1_29.jpg?_ex=240x240)
