セキュリティ

MCP TypeScript SDKの脆弱性:2026年10月の7件の対象版と更新後に要る設定変更

MCP TypeScript SDKの脆弱性:2026年10月の7件の対象版と更新後に要る設定変更

MCPサーバーとクライアントを作る公式ライブラリ「MCP TypeScript SDK」で、2026年10月に7件の脆弱性が公表されました。10月20日には5件がまとめて出ており、最も高いCVE-2026-111767はCVSS 8.6です。修正版は1.x系が@modelcontextprotocol/sdk 1.32.0、2.x系が@modelcontextprotocol/serverとclientの2.3.0です。ただし3件は版を上げただけでは塞がらず、コードか設定の変更が要ります。本記事では、7件の対象版と修正版、自社のMCPサーバーやクライアントが当てはまるかを確かめるコマンド、更新後に足す設定をTypeScriptのコードで示します。記載内容の根拠は、2026年10月28日時点で確認できる公開情報です。

まとめ:1.32.0・2.3.0へ上げ、さらに設定を3か所足して初めて塞がる

HTTPで公開しているMCPサーバーは、1.x系なら1.32.0以上、2.x系ならserver 2.3.0以上へ上げてください。@modelcontextprotocol/expressを使っていれば2.0.2以上も必要です。2026年10月28日時点のnpmの最新は、1.x系が1.32.2、2.x系のserverとclientが2.4.0でした。

更新だけで終わらないのは3件です。入力の要素数の上限(CVE-2026-111768)とトークンの宛先の検証(CVE-2026-111771)は、修正版で追加された設定が既定で無効のため、自分で有効にします。2.x系の共有インスタンスの混線(CVE-2026-111770)は、修正版が共有を拒むため、コードを直さずに上げると要求が失敗します。

急ぐべきは、複数の利用者がHTTPで接続できるサーバーと、信頼できないMCPサーバーへ接続するクライアントです。

2026年10月公表のMCP TypeScript SDKの脆弱性7件の対象版と修正版

7件はすべてmodelcontextprotocol/typescript-sdkのリポジトリでGitHub Security Advisoryとして公表されています。最初に全体を表で見渡し、そのあとで版の系統ごとの違いを整理します。

CVSSの高い順に並べたGHSA 7件の対象パッケージと修正版の一覧表

表の修正版は、勧告が「この版以上へ上げる」と案内している最初の版です。2.x系はパッケージが分かれているため、使っているものすべてを確かめます。

識別番号 CVSS 内容 1.x系の修正版 2.x系の修正版
CVE-2026-111767 8.6 タスクの持ち主を確かめない sdk 1.32.0 対象外
CVE-2026-111770 7.7 別の利用者へ応答が届く 対象外 server 2.3.0
CVE-2026-111768 7.5 1回の要求でメモリ枯渇 sdk 1.32.0 server 2.3.0
CVE-2026-104850 7.5 OAuthの秘密を別の認可先へ送る sdk 1.31.0 client 2.2.0
GHSA-f897-62hf-6gxq 7.5 本文サイズと一括送信の上限なし sdk 1.30.1 server 2.1.0ほか
CVE-2026-111771 6.8 別サービス向けトークンを受理 sdk 1.32.0 server 2.3.0ほか
CVE-2026-111769 6.5 別オリジンへのリダイレクト追従 sdk 1.32.0 client 2.3.0

CVSSはGitHub Advisory Databaseに載るCVSS v3.1の値です。GHSA-f897-62hf-6gxqは10月27日の公表で、28日時点ではCVE番号が付いていません。どの番号もリリースの順と公表の順が一致しないので、実際の判定は表の版で行います。CVSSの読み方の基礎は脆弱性とは?種類・CVE/CVSSの仕組みと発見から修正までの実務で確認できます。

修正版の公開が10月2日で勧告が10月20日という18日の差の読み方

修正を含む1.32.0とv2.3.0は、2026年10月2日にnpmへ公開されました。勧告の公開はその18日後の10月20日で、GHSA-f897-62hf-6gxqは修正版1.30.1の公開(9月23日)から勧告まで1か月以上空きました。

DependabotやRenovateのセキュリティ更新は、勧告がGitHub Advisory Databaseに載ってから動きます。10月上旬に通常の更新で1.32.0へ上げていれば修正は入っていますが、後述する設定変更は別の作業として残ります。

1.x系のsdkと2.x系の分割パッケージで影響範囲が異なる3つの例

1.x系は@modelcontextprotocol/sdkの1パッケージで、2.x系はserver・client・coreと、express・hono・nodeなどのアダプタに分かれています。分割の経緯はMCP TypeScript SDK v2とは?パッケージ分割とステートレス化の移行要点で解説しています。

CVE-2026-111767は1.x系だけの問題で、2.x系は対象外です。CVE-2026-111770は逆に2.x系のserverだけが対象で、1.x系は2月のCVE-2026-25536の修正(1.26.0)で同じ穴が塞がっています。CVE-2026-111771は2.x系でexpress 2.0.2とserver-legacy 2.3.1も必要で、「serverだけ上げた」状態が起きやすい点に注意してください。

サーバー側の脆弱性4件:セッション混線・メモリ枯渇・トークン誤受理の条件

サーバー側の4件は、いずれもHTTPで接続を受けるサーバーが対象で、stdioだけのサーバーは影響を受けません。

CVE-2026-111767:taskStoreを渡す1.x系サーバーの条件

GHSA-22jm-h49p-29qwによると、実験的なタスク機能のtaskStoreが、どのセッションがタスクを作ったかを確かめていませんでした。1つのInMemoryTaskStoreを共有する利用者どうしが、互いのタスクを一覧し、読み、取り消せた状態です。

対象は、HTTPのサーバーでMcpServerまたはServerにtaskStoreを渡している場合だけです。勧告は、ソースをtaskstoreで検索して何も出なければ対象外と案内しています。実験的なタスク機能は非推奨で、MCP仕様2026-07-28版で作り直されたMCP Tasks拡張に置き換わりました。1.32.0へ上げるか、すぐに上げられなければtaskStoreを外すか、セッションごとに作り分けます。

CVE-2026-111770:共有インスタンスで別の利用者へ応答が混ざる仕組み

GHSA-jm63-cq47-j5jpは、ある利用者への応答や通知が別の利用者へ届く問題です。SDKはメッセージをJSON-RPCのidだけで接続に結び付けていました。SDKのクライアントは要求の番号を0から振るため、通常の使い方でも番号は衝突します。

条件は、複数の利用者がHTTPで接続でき、サーバーやトランスポートを起動時に1回だけ作って使い回していることです。勧告によると、修正前はexpressやhonoなど各アダプタのREADMEの例がこの書き方で、写して作ったサーバーは当てはまりやすい状態でした。1.x系でも2026年2月に同種のCVE-2026-25536(1.10.0〜1.25.3が対象)が出ており、2回続けて同じ使い方が問題になっています。

CVE-2026-111768:4MiB以内の1要求でメモリが尽きる条件

GHSA-46jr-4wx8-v453(CVE-2026-111768)では、ツールの引数に含まれる配列の要素やオブジェクトのキーの数に上限がありませんでした。既定の本文上限4MiBに収まる1回の要求で、プロセスがJavaScript heap out of memoryで落ちます。認証より前にSDKへ要求が届く構成なら、資格情報も不要です。

10月27日のGHSA-f897-62hf-6gxqは、その手前の本文サイズとJSON-RPCの一括送信(バッチ)の件数に上限が無かった問題です。修正後は4MiBを超える本文に413、100件を超えるバッチに400を返します。勧告が示す注意点は、express.json()のような本文パーサーを置いても、バッチの件数は制限されないことです。どちらもツールの入力に配列やレコードを持つサーバーほど影響が大きくなります。

CVE-2026-111771:別サービス向けのトークンをaud未検証で受理

GHSA-rvq5-wwqv-78pqは、サーバー側のBearer認証に、トークンが自分宛てに発行されたか(audience)を確かめる手段が無かった問題です。1つの認可サーバーが複数のサービスへトークンを発行している環境では、別サービス向けの正規のトークンでMCPサーバーに入れました。

対象は、requireBearerAuth()かverifyBearerToken()を使い、自前のverifyAccessToken()でaudを見ていない場合です。MCP仕様のAuthorizationは、サーバーがトークンの宛先をRFC 8707に沿って検証することを必須(MUST)にしています。社内の認可サーバーを複数システムで共有している会社ほど、この条件に当てはまる構成です。トークン検証の設計全般はAPI不正アクセス対策の実装手順で扱っています。

クライアント側の脆弱性2件:OAuthの秘密とAPIキーが外へ出る経路

クライアント側の2件は、自社のアプリやエージェントが外部のMCPサーバーへHTTPで接続する場合が対象です。

CVE-2026-104850:MCPサーバーが指定した認可サーバーへ秘密を送る問題

10月6日のGHSA-6qxp-vccf-f47hでは、SDKのOAuthクライアントが、接続先のMCPサーバーの指定する認可サーバーへそのまま資格情報を送っていました。悪意のあるMCPサーバーが自分の認可サーバーを名乗れば、以前のサインインで保存したrefresh_tokenやclient_secretが、利用者の操作なしに渡ります。

修正版は1.x系が1.31.0、2.x系がclient 2.2.0で、保存する資格情報に認可サーバーのissuerを記録し、別の認可サーバーへは送らなくなりました。ClientCredentialsProviderやPrivateKeyJwtProviderなど同梱のプロバイダは、expectedIssuerを渡さない限り修正後も以前と同じ動作です。認可サーバーの仕組みと、クライアント登録の新方式はCIMD(Client ID Metadata Documents)とはで詳しく説明しています。

CVE-2026-111769:307転送で秘密が別オリジンへ届く経路

GHSA-6prh-2h8m-c8cwは、HTTPのクライアントトランスポートとOAuthの要求が、どのオリジンへのリダイレクトにも従っていた問題です。転送先にはX-API-Keyのような独自ヘッダとmcp-session-idが届き、307か308のときはrefresh_tokenやclient_secretを含む本文まで届きました。Authorizationヘッダは現行のランタイムのfetchが別オリジンで落とします。

1.x系は1.31.0までの全版が対象です。修正後は同じオリジン内のリダイレクトにしか従わず、redirectPolicy: 'follow'を指定すると以前の動作に戻ります。勧告は、管理外のホストへリダイレクトされた可能性があるなら、保持していたAPIキーとclient_secretを入れ替え、トークンを失効させるよう案内しています。

自社のMCPサーバー・クライアントが対象かをnpm lsとgrepで判定する手順

判定に必要なのは、入っている版と問題の機能の使用有無の2点で、どちらもリポジトリだけで確かめられます。

npm lsで@modelcontextprotocol配下の全パッケージの版の読み方

package.jsonの"^1.25.0"は範囲の指定で、実際の版ではありません。ロックファイルが解決した版を、間接依存まで含めて表示します。

# 1.x 系と 2.x 系の両方を、間接依存まで含めて表示する
npm ls @modelcontextprotocol/sdk @modelcontextprotocol/server \
  @modelcontextprotocol/client @modelcontextprotocol/express \
  @modelcontextprotocol/node @modelcontextprotocol/hono --all

# pnpm の場合
pnpm why @modelcontextprotocol/sdk

# 系列ごとの最新を確かめる
npm view @modelcontextprotocol/sdk dist-tags
npm view @modelcontextprotocol/server version

npxで起動する外部のMCPサーバーにもSDKが含まれるため、社内で配っているサーバーのパッケージも個別に確かめてください。

taskStoreやrequireBearerAuthの使用箇所を洗い出すgrep

勧告が条件に挙げる名前をまとめて検索します。

# サーバー側:タスク機能・Bearer 認証・トランスポートの作り方
grep -rniE "taskStore|requireBearerAuth|verifyBearerToken|StreamableHTTPServerTransport|createMcpHandler" \
  --include=*.ts --include=*.js --exclude-dir=node_modules .

# クライアント側:HTTP トランスポートと OAuth の呼び出し
grep -rniE "StreamableHTTPClientTransport|SSEClientTransport|authProvider|withOAuth|fetchToken" \
  --include=*.ts --include=*.js --exclude-dir=node_modules .

StreamableHTTPServerTransportやnew McpServerが、リクエストを処理する関数の外(モジュールの最上位や起動処理)にあれば、共有インスタンスの条件に当たります。requireBearerAuthが出たら、verifyAccessToken()でaudを見ているかを読みます。

修正版へ上げた後に要る3つの設定変更をTypeScriptのコードで実装

例は1.x系の@modelcontextprotocol/sdk 1.32系とExpressの組み合わせで書いています。2.x系でも考え方は同じで、勧告はcreateMcpHandler()に毎回新しいサーバーを作る関数を渡す書き方を案内しています。

McpServerとトランスポートをリクエストごとに作る形への書き換え例

共有インスタンスの問題は、要求ごと(またはセッションごと)にサーバーとトランスポートを作れば、修正前の版でも塞がります。2.x系は修正版で共有そのものが拒まれ、2回目のconnect()がALREADY_CONNECTEDで失敗するので、更新より先にこの形へ直しておきます。

import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";

const app = express();
app.use(express.json({ limit: "256kb" }));

// 要求ごとに新しいサーバーを作る(起動時に1回だけ作らない)
function buildServer() {
  const server = new McpServer({ name: "example-server", version: "1.0.0" });
  // server.registerTool(...) でツールを登録する
  return server;
}

app.post("/mcp", async (req, res) => {
  const server = buildServer();
  const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
  res.on("close", () => {
    transport.close();
    server.close();
  });
  await server.connect(transport);
  await transport.handleRequest(req, res, req.body);
});

app.listen(3000);

セッションを使うサーバーなら、sessionIdGeneratorを設定し、セッションごとにサーバーとトランスポートを1組ずつ持たせます。

maxToolInputElementsと本文サイズで入力の上限を決める設定

CVE-2026-111768の勧告は「更新だけでは何も変わらない」と明記し、2つの設定を求めています。1つはツールの引数の要素数の上限maxToolInputElementsで、既定は無制限です。もう1つは本文サイズの上限で、ツールが本当に必要とする大きさまで下げます。

// ツールの引数に含まれる配列の要素とキーの合計の上限(既定は無制限)
const server = new McpServer(
  { name: "example-server", version: "1.0.0" },
  { maxToolInputElements: 10_000 }
);

// 本文を自分で読ませる場合は、トランスポートに上限(バイト)を渡す
const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: undefined,
  maxRequestBodySize: 256 * 1024,
});

// express.json() で先に解析する場合は、パーサー側の limit が上限になる
app.use(express.json({ limit: "256kb" }));

1.32.2のソースを読むと、maxRequestBodySizeは解析済みの本文(req.body)を渡したときには適用されません。前の例のようにexpress.json()を使う構成では、パーサーのlimitを必ず設定してください。すぐに更新できない場合は、リバースプロキシで本文サイズを制限するのが勧告の示す回避策です。

expectedResourceでトークンの宛先を確かめる実装

CVE-2026-111771も既定で無効の設定を有効にします。勧告によると、expectedResourceの指定と、verifyAccessToken()がresourceを返す変更を同時に入れる必要があり、片方だけだと全要求が401になります。

import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";

const verifier = {
  async verifyAccessToken(token: string) {
    // verifyJwt は署名と有効期限を検証する自前の関数
    const claims = await verifyJwt(token);
    return {
      token,
      clientId: claims.client_id,
      scopes: (claims.scope ?? "").split(" "),
      expiresAt: claims.exp,
      // トークンの aud を resource として返す(URL 型)
      resource: new URL(claims.aud),
    };
  },
};

app.use(
  "/mcp",
  requireBearerAuth({
    verifier,
    // 認可サーバーがこのサーバー向けトークンの aud に入れる値
    expectedResource: new URL("https://mcp.example.com/mcp"),
  })
);

別サービス向けのトークンは、これで401になります。audが配列で届く認可サーバーでは、自社のサーバーのURLを含む要素を選んで返してください。更新前の版では、verifyAccessToken()の中でaudが自社のサーバーを含まないトークンを拒否すれば、どの版でも同じ効果が得られます。クライアント側の2件は、同梱プロバイダへのexpectedIssuerの指定と、更新前ならリダイレクトを拒むfetch(redirect: 'error')を渡す対応で足ります。

HTTPで公開するMCPサーバーを更新で済ませるか設計から見直すかの判断基準

7件の問題は、認可・入力上限・インスタンスの持ち方というMCPサーバーの設計そのものに集中しています。

stdioだけの社内ツールは通常の依存更新の周期で足りるという線引き

Claude DesktopやIDEから子プロセスとして起動するstdioのMCPサーバーは、サーバー側の4件とGHSA-f897のいずれも対象外です。この構成では利用者が1人で、ネットワークからの要求も受け付けません。そのため、次の通常の依存更新で1.32.2以上か2.4.0以上へ上げれば十分で、当日中の対応は過剰です。

例外は、stdioのサーバーの中からHTTPで外部のMCPサーバーや認可サーバーへ接続している場合です。クライアント側の2件の条件に入るため、外部APIのclient_secretを持つなら更新を早めます。MCPの全体像はMCPとは?AIと外部ツールをつなぐ標準規格で整理しています。

複数の利用者へHTTPで公開するサーバーは認可と上限の設計から直す条件

社外の取引先や複数部署の利用者がHTTPで接続するMCPサーバーは、更新だけでは終えないでください。今回の7件のうち3件は設定を足さないと塞がらず、2件(CVE-2026-25536とCVE-2026-111770)は同じ使い回しの書き方が2回続けて問題になりました。READMEの例を出発点に作ったサーバーは、インスタンスの持ち方・トークンの宛先の検証・入力の上限の3点を、勧告と照らして1つずつ確かめる必要があります。

ツールの数が多く、どの入口でどの認可が効いているかを社内で説明できない場合は、外部の診断で抜けを洗い出すほうが早く終わります。一創の脆弱性診断・セキュリティ診断では、MCPサーバーを含むWeb APIの認可と入力検証を点検しています。

MCP TypeScript SDKの脆弱性対応でよく受ける質問と回答

MCP TypeScript SDKの7件の対応について、現場で出やすい疑問をまとめました。

悪用は確認されていますか?更新はどのくらい急ぐべきですか?

2026年10月28日時点で、7件の勧告に悪用の記載はありません。急ぐかどうかは公開範囲で決まります。インターネットや社外から到達できるHTTPのMCPサーバーは、メモリ枯渇の2件が認証なしで成立しうるため、当日中に更新と上限の設定を入れてください。stdioだけのサーバーは通常の更新周期で足ります。信頼できないMCPサーバーへ接続するクライアントは、その中間として週内の更新を目安にします。

1.x系のまま使い続けても修正は受けられますか?

受けられます。今回の修正は1.x系にも1.32.0として出ており、10月23日には1.32.2が公開されました。2.x系への移行を脆弱性対応と同時に進めると、不具合の原因を切り分けにくくなります。まず1.x系の中で上げて設定を足し、移行は別の計画にするのが安全です。移行の作業量はMCP TypeScript SDK v2の移行要点で見積もれます。

更新したらリクエストが失敗するようになったのはなぜですか?

原因は3つ考えられます。2.x系でALREADY_CONNECTEDが出るなら、サーバーかトランスポートを共有しているので、要求ごとに作る形への修正が必要です。413や400が返るなら、4MiBの本文上限か100件のバッチ上限に当たっているので、正当な要求ならmaxRequestBodySizeを上げます。全要求が401なら、expectedResourceだけを設定し、verifyAccessToken()がresourceを返していません。

Python SDKやFastMCPだけを使っている場合は対象ですか?

今回の7件はnpmで配布されるTypeScript版のパッケージの問題で、Python版のSDKは対象外です。ただしFastMCPには10月23日に2件の勧告が出ており、3系は3.4.10、4系は4.1.2が修正版になります。うちGHSA-vqqp-x5qm-5qp4は、クライアントの秘密を別の認可サーバーへ送りうる問題で、TypeScript版のCVE-2026-104850と同じ種類でした。FastMCPの版の追い方はFastMCP 4とはにまとめています。

リダイレクトの問題で秘密が漏れたかどうかは確かめられますか?

SDKの側に記録は残らないため、接続先のアクセスログで別オリジンへの307や308の応答が無いかを見るのが手がかりです。社外のサーバーでログを見られないなら、漏れた前提でAPIキーとclient_secretを入れ替え、トークンを失効させてください。MCP経由の権限の漏れ方はPlaywright MCPのセキュリティでも別の事例を扱っています。

関連記事

お気に入りに入れた記事の一覧

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2025.02.27 コラム トラッキングビーコン(Webビーコン)とは?仕組み・用途・確認と対策を徹底解説
  2. 2026.10.27 テックブログ Brotli 脆弱性:CVE-2026-111497の影響確認とNode.js・Python・.NETの更新手順
  3. 2026.10.27 テックブログ Joshin(ジョーシン)不正アクセス:最大600万件の対象とサブスク初期パスワードの対処
  4. 2026.07.09 テックブログ Muse Imageとは?Metaの画像生成AIの使い方・API料金(1枚0.01ドル)と日本での提供状況【2026年10月】
  5. 2026.10.23 テックブログ Renta!はいつ再開?不正アクセスでメールアドレス等が流出したおそれ・再開時のパスワード再設定と運営側の対応

RELATED POSTS 関連記事

目次