FlawOpen

flawopen.com/AI Security/litellm-mcp-preview-command-injection-cve-2026-42271

● CVE-2026-42271 · CVSS v4 8.7[1] · 高
セキュリティ研究 · FlawOpen

LiteLLM MCP コマンドインジェクション:CVE-2026-42271

GTIGはCVE-2026-42271の悪用を確認。有効なLiteLLMキーでMCPプレビュー経由のコマンド実行が可能でした。1.83.7以降へ更新してください。[1], [6], [8]

CVSS ベクトルCVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:N/SA:N[1]
💡 わかりやすい解説 (ELI5)

工房では、道具を登録する前に来訪者が試せます。試用台は工房の強力な機械を起動できるため、指示を出せるのは管理者だけであるべきです。脆弱な LiteLLM では、受け入れられた入館証を持つ人なら誰でも試用台を使えました。別の Starlette の欠陥は、再構成された URL でアクセスを判断する門番を惑わせる可能性があります。それぞれの境界を個別に修正する必要があります。 別の窓口では、来訪者が荷札にスラッシュや疑問符を書き込めます。係員が住所を組み立て直すとき、その文字列を貼り合わせて新しい通路だと読み違えますが、荷物は元の廊下を進みます。これが Starlette における Host とパスの別個の混同です。[1], [3], [5]

主要な概念と専門用語

Model Context Protocol (MCP)
AI ゲートウェイなどのアプリケーションが外部のツールやデータソースに接続するためのプロトコルです。LiteLLM のプレビューエンドポイントは、保存前に MCP サーバー設定をテストします。[1]
stdio トランスポート
ローカルの子プロセスを起動し、標準入力と標準出力でメッセージを交換する MCP 接続方式です。プロセスは LiteLLM プロキシホスト上で、プロキシサービスの OS 権限で動作します。[1], [2]
ロールベース認可
必要なロールを持つ ID だけに操作を許可するサーバー側の検査です。CVE-2026-42271 では、保存処理にあった PROXY_ADMIN 検査がプレビュー経路にありませんでした。[1], [2]
CVE-2026-48710(Starlette BadHost)
独立した Starlette の脆弱性です。不正な Host ヘッダーにより request.url.path がルーティングに使われたパスと異なる場合があります。Horizon3 は、特定の依存関係の組み合わせで LiteLLM のパスベース認証を回避できると報告しました。CVE-2026-42271 の一部ではありません。[3], [5], [4]
MCP stdioコマンド許可リスト
LiteLLMがstdioトランスポートで許可する実行ファイルのbasename集合です。設定検証時と、古いレコードに対するクライアント作成前に再確認します。許可されたランタイムも引数を解釈できるため、サンドボックスではありません。[8]

フレームワーク対応

ステップ・バイ・ステップの攻撃フロー

ステップ 1

LiteLLM のバージョンとエンドポイントの公開状況を確認する

メンテナーのアドバイザリーによると、影響範囲はLiteLLM >=1.74.2かつ<1.83.7で、有効なプロキシAPIキーが必要です。修正前は、低権限の内部ユーザー用キーを含む、認証済みキー所有者なら誰でもプレビュールートに到達できました。GTIGはCVE-2026-42271を悪用確認済みリストに含めていますが、このCVEの前提条件はメンテナーアドバイザリーの認証済み脅威モデルに従ってください。[1], [6]

ステップ 2

低い権限のキーで管理者向けプレビュー操作に到達できる

エンドポイントは stdio コマンド、引数、環境変数を含む完全な MCP サーバー設定を受け付けました。サーバーはキーを認証しましたが PROXY_ADMIN ロールを確認しなかったため、認証済みのキー保有者なら誰でもプレビューを呼び出せました。[1]

ステップ 3

プレビューがプロキシホスト上でプロセスを起動する

送信された stdio 設定を試すため、LiteLLM は MCP クライアントを作成し、プロキシサービスの権限で設定された子プロセスを起動しました。これはゲートウェイホスト上のコマンド実行であり、AI モデルが危険な文を返すだけの問題ではありません。[2], [8]

ステップ 4

別の Starlette の欠陥が認証境界を弱める可能性がある

Horizon3 は、影響を受ける Starlette が存在する場合、CVE-2026-48710 によってパスベース認証が Starlette の選んだルートとは異なる request.url.path を見る可能性があると報告しました。研究者はこれを CVE-2026-42271 と組み合わせ、対象環境で API キーの前提をなくしたと報告しています。このチェーンは研究者の報告として記載してください。2 つの CVE は原因も修正も別です。[5], [3], [4]

ステップ 5

両方の境界を修正し、実際に解決されたパッケージを確認する

LiteLLM 1.83.7ではプレビュールートが修正され、PROXY_ADMINが必要になり、tools/listにも明示的な認証が追加されました。さらに新規・更新リクエストでコマンド許可リストを検証し、_create_mcp_clientでも再検証して旧設定を防ぎます。許可リストはサンドボックスではなく、許可されたランタイムも引数を解釈します。StarletteはCVE-2026-48710を別途1.0.1で修正しました。実際に解決されたパッケージ組み合わせを確認し、報告されたチェーンは独立して評価してください。[1], [8], [4], [7]

ステップ 6

最近のキャンペーン情報(2026年10月7日報告)

Black Lotus Labs は、PoeLLM マルウェアのサンプルが /mcp-rest/test/connection を標的にした可能性が高いと報告しました。BleepingComputer も、同キャンペーンで CVE-2026-42271 の悪用が試みられたと報じています。この報告は、すべての感染ホストがこの CVE で侵害されたことや、LiteLLM の標的すべてが脆弱だったことを示すものではありません。これは現在の標的化を示す証拠であり、この脆弱性に帰属する被害数ではありません。[9], [10]

根本原因の分析 (Root Cause)

LiteLLM の問題は、2 つの MCP プレビュー経路でロール確認が欠けていたことです。有効なプロキシ API キーがあれば、PROXY_ADMIN ロールがなくても呼び出せました。接続プレビューは呼び出し元が指定した stdio 設定を受け取り、プロキシプロセスの権限でコマンドを起動しました。別の Starlette の脆弱性では、不正な Host ヘッダーによって request.url.path が Starlette のルーティング対象パスと異なる場合がありました。Horizon3 は、この挙動を LiteLLM と組み合わせると、パスに基づく API キー検証を回避できるチェーンを報告しています。これらは別個の脆弱性です。LiteLLM の認可とコマンド実行の境界を修正し、Starlette を 1.0.1 以降に更新してください。[1], [8], [3], [4], [5]

ソースコード比較:脆弱 vs 堅牢化

この抜粋は、マージ済みLiteLLM修正の実行境界を示します。stdioクライアントを作成する前にコマンドのbasenameを確認するため、古いDB/設定レコードも検査されます。パッチは新規・更新サーバー設定も検証し、両方のプレビューエンドポイントをPROXY_ADMINに制限します。/test/tools/listにはuser_api_key_auth依存も明示的に追加されました。許可リストはサンドボックスではなく、許可されたランタイムも引数を解釈できます。プレビューは管理者に限定し、プロキシは最小権限で実行してください。[1], [2], [8]

ソース抜粋: LiteLLM stdioクライアントの検証コード抜粋

脆弱な実装
# _create_mcp_client:stdio コマンドのガード追加前の実装。
if server.command and server.args is not None:
    stdio_config = MCPStdioConfig(
        command=server.command,
        args=server.args,
        env=resolved_env,
    )
堅牢化されたセキュアパッチ
# _create_mcp_client:DB/設定に残る既存レコードも再検証します。
if server.command:
    base_command = os.path.basename(server.command)
    if base_command not in MCP_STDIO_ALLOWED_COMMANDS:
        raise HTTPException(
            status_code=403,
            detail="MCP stdio command is not in the allowlist",
        )

if server.command and server.args is not None:
    stdio_config = MCPStdioConfig(
        command=server.command,
        args=server.args,
        env=resolved_env,
    )

エンジニアリング&システム堅牢化チェックリスト

参考資料

← AI Security Directory →