技術 約9分で読めます

LiteLLM CVE-2026-42271がCISA KEV入り、MCP stdioテスト経由でRCE

いけさん目次

TL;DR

影響 LiteLLM 1.74.2〜1.83.7未満のMCPサーバー設定テストエンドポイントで任意コマンド実行。単体は低権限APIキー要、Starlette CVE-2026-48710とのチェーンで未認証RCE(リモートコード実行)

対応 LiteLLM 1.83.7以上 + Starlette 1.0.1以上へのアップデート。CISA KEV(悪用確認済み脆弱性カタログ)追加済み、対応期限2026年6月22日

暫定 リバースプロキシで /mcp-rest/test/connection/mcp-rest/test/tools/list をブロック。保存済みLLMプロバイダキーのローテーション


The Hacker Newsの記事は「CVE-2026-42271が悪用され、未認証RCE(リモートコード実行)へチェーンできる」と報じている。
GitHub AdvisoryNVD上のCVE-2026-42271単体は、PR:L、つまり低権限の認証ありだ。
未認証になるのは、StarletteのHostヘッダー処理バイパスであるCVE-2026-48710が同じデプロイに残っている場合のチェーンとして扱う。

3月に書いたTeamPCPによるLiteLLM PyPIパッケージ汚染は、LiteLLMの配布経路そのものを踏まれた話だった。
今回のCVE-2026-42271は、正規のLiteLLM Proxyを動かしていても、MCP(Model Context Protocol)の標準入出力(stdio)設定のプレビュー機能とAPIキー権限がずれるとホスト上のコマンド実行に届く。
同じLiteLLMでも、確認する場所はパッケージ履歴ではなく、稼働中のProxyバージョン、MCP関連エンドポイント、Starlette依存関係、保存済み認証情報になる。

問題の入口は2つのMCPテストエンドポイント

対象はLiteLLM 1.74.2以上、1.83.7未満。
GitHub Advisoryでは、次の2つのエンドポイントが挙がっている。

エンドポイント本来の用途
POST /mcp-rest/test/connectionMCPサーバー設定の接続確認
POST /mcp-rest/test/tools/list保存前のMCPサーバーからツール一覧を取得

これらは保存前のMCPサーバー設定をプレビューするためのAPIだが、リクエストボディに完全なサーバー設定を受け取っていた。
stdioトランスポートの設定では commandargsenv が含まれる。
LiteLLMはその設定で接続を試し、指定されたコマンドをLiteLLM Proxyプロセスの権限でサブプロセスとして起動した。

修正前のアクセス制御は、Proxy APIキーが有効かどうかだけだった。
PROXY_ADMIN ロールは要求されず、内部ユーザー用の低権限キーでもテストエンドポイントを叩けた。
修正版の1.83.7では、保存エンドポイントと同じくテスト側も PROXY_ADMIN に限定された。

オープンソースMCPサーバー50件スキャンで書いた「ツール承認後に内部コマンドが自動実行される」問題と似ているが、今回はローカルのMCPサーバーではなくLiteLLM Proxyの管理API側で起きている。
MCP stdioは、設計上「コマンドを起動してサーバーと話す」仕組みを持つ。
そのため、設定値の投入権限とコマンド起動権限を同じ扱いにすると、そのままホスト上のコマンド実行になる。

1.83.7の修正はロールチェックだけではない

LiteLLM公式の4月のセキュリティ更新と、修正PR(#25343)を見ると、1.83.7の対策はテストエンドポイントの PROXY_ADMIN 必須化だけではない。
stdioトランスポートで起動できるコマンドの絞り込み、リクエスト受理時の検証、既存設定を読み直した時の再検証が入っている。

変更点
コマンド許可リストnpxuvxpythonpython3nodedockerdeno のみを標準許可
リクエスト検証新規作成・更新のMCP stdio設定で、command のベース名を許可リストと照合
ランタイム再検証DBや設定ファイルから復元された古いMCPサーバー定義も、実行直前に再チェック
権限チェック/mcp-rest/test/connection/mcp-rest/test/tools/listPROXY_ADMIN のみに制限

追加のstdioランチャーが必要な環境では LITELLM_MCP_STDIO_EXTRA_COMMANDS で許可リストを広げられる。
ただし、ここにシェルや汎用実行ラッパーを足すと、今回潰した境界を自分で開け直すことになる。
標準許可リストにある pythonnode も引数次第では任意コードを動かせるので、1.83.7以降でも「stdio MCP設定を編集・テストできる人」は実質的にProxyホスト上でコード実行できる管理者として扱う。

調査中にCVE-2026-30623という別番号も出てくる。
これはOX SecurityのMCP stdio問題の文脈で、LiteLLMのMCPサーバー作成・更新・プレビュー経路を広めに扱ったものだ。
CISA KEV入りしているCVE-2026-42271は、GitHub Advisory上では特に2つのプレビュー用テストエンドポイントの認可不足として整理されている。
CVE番号でチケットを分ける場合でも、現場での対処は同じで、LiteLLM 1.83.7以降への更新、stdio MCP設定の見直し、非管理者キーでテストAPIへ届かないことの確認をセットにする。

KEV入りで悪用済み扱いになった

CISA(米国サイバーセキュリティ・インフラセキュリティ庁)のKEV(悪用確認済み脆弱性カタログ)JSONでは、CVE-2026-42271の追加日は2026年6月8日、期限は2026年6月22日になっている。
対応内容は、ベンダー指示に従った緩和、クラウドサービスの場合はBOD 22-01に沿った対応、緩和策がない場合の利用停止だ。

CVSS(Common Vulnerability Scoring System。脆弱性の深刻度を数値化する方式)は情報源で少し違う。
GitHubのCVSS v4.0は8.7 HIGH。
NVDのCVSS 3.1は8.8 HIGHで、ベクトルは AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H になっている。
AV:N はネットワーク越しに届くこと、PR:L は低権限を要求すること、UI:N はユーザー操作を要求しないことを示す。

CISAの短い説明も、任意の認証済みユーザー、低権限の内部ユーザーキーを持つユーザーを含む、と書いている。
この「低権限で足りる」がCVE-2026-42271単体の見落としやすい部分だ。
Proxyの利用者向けキーを発行している環境では、管理者キーだけを守っていても、MCPテストエンドポイントからProxyホストの権限へ上がれる経路が残る。

Starlette BadHostが残ると認証条件が外れる

Horizon3.aiはCVE-2026-42271とCVE-2026-48710のチェーンを検証している。
CVE-2026-48710はStarlette 1.0.1未満のHostヘッダー検証不備で、NVDの説明では、StarletteがHTTP Host ヘッダーを検証せずに request.url を再構築し、実際に要求されたパスと request.url.path がずれることがある、としている。
パスベースの認可を request.url 側で見ているミドルウェアやエンドポイントでは、この差で認証チェックをすり抜ける。

Horizon3.aiの検証では、Starlette 1.0.0以下を含むLiteLLMデプロイでこのバイパスを使うと、CVE-2026-42271の「有効なProxy APIキーが必要」という条件が外れる。
その状態で /mcp-rest/test/connection/mcp-rest/test/tools/list にstdio設定を渡すと、認証なしのRCEになる。
Starlette側のCVSSは6.5 MEDIUMだが、LiteLLMのようにパスベース認証とコマンド実行エンドポイントが同居していると、単体スコアより重い結果になる。

CVE-2026-48710は、「Starletteを使っているだけで即RCE」という脆弱性ではない。
Starlette Advisoryの説明は、ルーティングが実際のHTTPパスを見る一方で、アプリ側の認可処理が request.url.path を見ていると、Hostヘッダー由来の再構築URLと実パスがずれて認可が外れる、というものだ。
つまり成立条件は「Starlette 1.0.0以下」「セキュリティ判断に request.url / request.url.path を使う」「問題のあるリクエストがアプリまで届く」の組み合わせになる。

OSTIFのBadHost解説は、nginx、Apache httpd、Cloudflareのように不正なHostヘッダーを前段で拒否・正規化する構成なら緩和になりうる、と書いている。実際の設定でも確認する。
LiteLLMやvLLMのようなLLMゲートウェイを、uvicornやgranianなどのASGIサーバーで直接外部公開している場合は、前段プロキシに守られている前提を置かずに確認する。
HTTP/3やQUICを終端するフロントエンドを使っている場合も、HTTP/1.1のHost検証と同じ挙動とは限らない。

Proxyが持つ認証情報まで確認する

パッチはLiteLLM 1.83.7以降とStarlette 1.0.1以降。
すぐに上げられない場合、GitHub AdvisoryはリバースプロキシやAPIゲートウェイで POST /mcp-rest/test/connectionPOST /mcp-rest/test/tools/list をブロックする回避策を出している。
Horizon3.aiはそれに加えて、ネットワーク到達範囲の制限、Proxyに保存された認証情報のローテーション、異常なHostヘッダーとサブプロセス実行ログの確認を挙げている。

LiteLLM ProxyはLLM APIの中継点なので、プロセス環境やDBにはOpenAI、Anthropic、Bedrock、Azure OpenAIなどのプロバイダキーが集まりやすい。
RCEの成否だけを見て終わると、Proxyが保持していたキーの悪用を拾えない。
KEV入り後に確認する順番は、稼働バージョン、Starlette依存関係、2つのMCPテストエンドポイントへのアクセスログ、Proxyホスト上の不審なサブプロセス、保存済みLLMプロバイダキーのローテーションになる。

実際の確認は、ホスト側のPython環境ではなく「稼働中のLiteLLM Proxyコンテナや仮想環境の中」で見る。
バンドル済みのDockerイメージや古いvenvを使っていると、ホストで pip list した結果と本番プロセスの依存関係がずれる。

python - <<'PY'
import importlib.metadata as m

for package in ("litellm", "starlette", "fastapi"):
    try:
        print(f"{package}: {m.version(package)}")
    except m.PackageNotFoundError:
        print(f"{package}: not installed")
PY

コンテナなら docker exec <container> python ... で同じ確認をする。
LiteLLMが 1.74.2 以上 1.83.7 未満、またはStarletteが 1.0.0 以下なら、インターネット非公開でも優先対応に回す。
VPN内、社内LAN、CI/CD用ネットワーク、検証用サブドメインのような「信頼済み」扱いの場所に置かれたProxyほど、低権限キーや開発用キーが広く配られていることがある。

ログ側では、少なくとも次を検索する。

/mcp-rest/test/connection
/mcp-rest/test/tools/list

あわせて、通常の利用では出ないHostヘッダー、LiteLLMプロセスの子プロセス起動、コンテナ内から外部へ出る不審な通信を見る。
見つかった場合は、LiteLLMのAPIキーだけでなく、Proxyが保持していたLLMプロバイダキー、クラウド認証情報、DB認証情報までローテーション対象に含める。

runZeroもLiteLLMインスタンス探索の記事で、CVE-2026-42208、CVE-2026-42203、CVE-2026-42271の複数脆弱性がRCEへチェーンされうると整理している。
CVE-2026-42208は4月に公開された認証前SQLインジェクションで、5月時点ですでに悪用確認が出ていた。
LiteLLMでは、Proxyの認証、MCP stdio、Starlette依存、保存済みキーを同じインスタンス単位で追う。

参考