LiteLLMのMCP認証バイパスCVE-2026-59822。偽のAuthorizationヘッダが空のUserAPIKeyAuth()に化ける機構
対象の目安: LiteLLMやMCPサーバーを社内で運用する開発基盤担当と情報システム担当 / 実務

社内でLLMの呼び出しを1か所に集めるAIゲートウェイは、モデルのAPIキーだけを持っているわけではありません。Model Context Protocol(MCP)のゲートウェイ機能を有効にしていれば、GitHubやSlackや社内APIへ接続するための資格情報も同じ場所に集まります。その入口の認証が、キー検証で弾かれたはずのAuthorizationヘッダで素通りしていたというのが、BerriAIのLiteLLMに割り当てられたCVE-2026-59822です。
NVDの説明は次の内容です。1.84.0より前のLiteLLMのMCP Streamable HTTPエンドポイントで、偽造したAuthorizationヘッダがOAuth2パススルー用のフォールバック経路を起動し、失敗したLiteLLMキーの検証が空の UserAPIKeyAuth() オブジェクトに置き換えられることで、有効なLiteLLMキーなしにMCPのツールへ到達できました。修正は1.84.0です。CISAは2026年9月2日、実際の悪用の証拠にもとづいてこの脆弱性をKnown Exploited Vulnerabilities(KEV)カタログへ追加しています。
この記事は、LiteLLMやMCPサーバーを社内で立てている開発基盤担当と情報システム担当に向けて、GitHub Security Advisory、NVD、CVEレコード、CISAのKEVカタログ、LiteLLMの修正コミットとリリースノートという一次情報から、機構、影響の見極め方、暫定策、更新後の後始末を整理します。攻撃を再現する手順は扱いません。確認や設定変更は自組織が管理する環境に限って行い、他者の環境への試行は不正アクセス禁止法などの関連法令に触れます。記述は執筆時点(2026年9月6日)に確認できた範囲に限ります。
一次資料でそろえた事実
まず、参照できる値を並べます。GitHub Security Advisoryの識別子はGHSA-7488-6r32-c95qで、GitHub Advisory Database上のsummaryは「LiteLLM: MCP Authentication Bypass via OAuth2 Passthrough Fallback」、severityはhighです。影響を受ける範囲はpipパッケージlitellmの1.84.0未満、修正版は1.84.0以上です。NVDが生成したCPEの照合条件も cpe:2.3:a:litellm:litellm:* のversionEndExcludingが1.84.0で、同じ区切りになっています。
| 項目 | 値 |
|---|---|
| CVE | CVE-2026-59822 |
| GHSA | GHSA-7488-6r32-c95q |
| 影響を受ける版 | litellm 1.84.0 未満 |
| 修正版 | 1.84.0(2026年5月14日公開) |
| CWE | CWE-287 Improper Authentication / CWE-306 Missing Authentication for Critical Function |
| CVSS v4.0 | 8.8 HIGH(CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N、GitHub付与) |
| CVSS v3.1 | 8.2 HIGH(CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N、NVD一次評価) |
| KEV dateAdded / dueDate | 2026-09-02 / 2026-09-16 |
| KEV forensicTriage | No |
| KEV knownRansomwareCampaignUse | Unknown |
| SSVC(CISA) | Exploitation: active、Automatable: yes、Technical Impact: partial |
CVSSの2つの値は、評価者も版も違います。v4.0の8.8はGitHub Security Advisoryのソース(security-advisories@github.com)がSecondaryとして付けたもので、v3.1の8.2はNVD(nvd@nist.gov)がPrimaryとして付けたものです。どちらもVI(またはI)をLowに置いている点が共通しています。読み出し寄りの影響として評価された、ということです。この点は後述のSSVCのTechnical Impactがpartialであることとも整合します。
公表日については、参照する資料で値が異なります。NVDのpublishedは2026-07-08T20:16:57で、lastModifiedは2026-09-03T13:05:59、vulnStatusはAnalyzedです。GitHub側のアドバイザリページに埋め込まれた日時はこれより前を指しており、単一の公表日として断定できる値がありません。この記事では、確実に一致している修正版のリリース日(2026年5月14日)とKEV追加日(2026年9月2日)を時間軸の基準として使います。報告者としてはGHSAのクレジット欄にyaarasの名前が載っています。
日本側の状況も確認しておきます。JVNDBのMyJVN検索でLiteLLMを検索した結果は、2026年9月6日時点で該当エントリなしでした。JPCERT/CCやIPAによるLiteLLM固有の注意喚起も見当たりません。国内の窓口経由の情報を待つ運用にしていると、この種のOSS由来の脆弱性は拾えないことがあります。
NVDのCVE-2026-59822は、published 2026-07-08T20:16:57.683、lastModified 2026-09-03T13:05:59.573、vulnStatus Analyzedです。metricsにはcvssMetricV40(security-advisories@github.com、Secondary、baseScore 8.8 HIGH)とcvssMetricV31(nvd@nist.gov、Primary、baseScore 8.2 HIGH)が記録されています。weaknessesはsecurity-advisories@github.comをsourceとするSecondaryのCWE-287とCWE-306です。cisaExploitAddは2026-09-02、cisaActionDueは2026-09-16です。参照リンクには修正コミット、Pull Request #26463、v1.84.0のリリース、GHSA、KEVカタログ、そしてWiz Researchのブログが含まれます。
失敗したキー検証が空のUserAPIKeyAuth()に置き換わる機構
修正はコミット73869f0faf7d11ee21adcb5f91b8c33a340b6c2c(Pull Request #26463)で入りました。変更されたのは litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py とそのテストです。コミットメッセージとリリースノートに、直された内容が2つ書かれています。
1つ目がCVE本文に対応する経路です。MCPリクエストの認証処理は、まずLiteLLM専用ヘッダである x-litellm-api-key を見ます。これが無く、標準の Authorization ヘッダだけがある場合、その値をまずLiteLLMの仮想キーとして検証します。ここで401や403になったとき、修正前の実装は「これはLiteLLM宛のキーではなく、上流のMCPサーバー向けのOAuth2トークンをパススルーしているのだろう」と解釈し、例外を捕まえて空の UserAPIKeyAuth() を返していました。このフォールバックはOAuth2認証を必要とする上流MCPサーバーへの対応として追加されたものでしたが、対象サーバーの auth_type 設定に関係なく発火しました。結果として、検証に失敗したという事実が、権限を絞る方向ではなく身元を消す方向へ倒れます。
この経路が成立する条件も押さえておきます。捕捉していたのは401と403だけで、それ以外のコードはそのまま伝播します。たとえばDBを接続していない構成では、仮想キーの検証が no_db_connection のコード400で失敗するため、フォールバックには入らずリクエストは拒否されます。素通りが起きるのは、認証バックエンドが無効なキーに対して401か403を返す構成です。
2つ目は同じ修正で直った公開ルート判定です。修正前は ".well-known" in str(request.url) という書き方で、URL全体に対する部分一致でした。str(request.url) にはクエリ文字列が含まれるため、任意のMCPルートに ?.well-known を付けるだけで公開ルート扱いになりました。修正後は request.url.path.startswith("/.well-known/") に変わり、パスの前方一致だけを見るようになっています。CVE-2026-59822の説明文が記載しているのはOAuth2フォールバック側だけですが、同じコミットでこちらも塞がれています。
要点だけを概念として書き直すと、変更の方向は次のようになります。実際の差分ではなく、判断の流れを示すための再構成です。
# 修正前の判断(概念): LiteLLMキーの検証に失敗したら匿名セッションへ読み替えていた
try:
return validate_litellm_key(request)
except (HTTPException, ProxyException):
return UserAPIKeyAuth() # 身元が空のまま先へ進む
# 修正後の判断(概念): 対象MCPサーバーがすべて auth_type=oauth2 のときだけフォールバックする
try:
return validate_litellm_key(request)
except (HTTPException, ProxyException):
if _target_servers_use_oauth2(target_servers):
return UserAPIKeyAuth()
raise
修正で新設されたヘルパーは2つです。_extract_target_server_names_from_path は /mcp/{server_name} と /{server_name}/mcp の形だけを解決し、それ以外の形は空リストを返します。_target_servers_use_oauth2 は、対象となるサーバーがすべて auth_type == oauth2 のときにだけTrueを返します。対象が空、名前が解決できない、oauth2以外のサーバーが1つでも混ざる、のいずれでもフォールバックは動かず、そのまま認証エラーになります。x-mcp-servers ヘッダで対象が明示されている場合はそちらが優先され、明示的な空リストも同じくfail closedとして扱われます。
ProxyException のコードの扱いについては、経緯を分けて書いておきます。73869f0はHTTPExceptionとProxyExceptionの捕捉を1つにまとめる際に int(e.code) を導入しました。ProxyException は code を文字列へ正規化するため、code=None で渡された場合は int("None") がValueErrorになり、認証エラーが未処理の500へ書き換わります。この回帰は同じPull Requestの後続コミット0a4640fで、整数と文字列の両方の形と比較する書き方に直されました。修正コミットを1つだけ読んで判断すると、この部分の挙動を取り違えます。
匿名セッションがどのMCPサーバーまで届くのか
身元が空のセッションが作れたとして、そこから何ができるかは構成によって変わります。Pull Request #26463の本文は、この点について具体的に書いています。get_allowed_mcp_servers が allow_all_keys=True に設定されたサーバーを無条件に和集合していたため、未認証の呼び出し元がそれらのサーバーでツールを完全に使える状態になった、という記述です。
allow_all_keys はLiteLLMのドキュメントで「サーバーを、キーやチームのMCP権限にそのサーバーが列挙されていない場合でも、すべてのLiteLLM APIキーから利用可能にする」設定と定義されています。運用の都合で立てた社内向けMCPサーバーにこの設定を付けていると、身元が空のセッションからも同じ扱いで見えることになります。
権限モデルの既定値も見ておきます。LiteLLMのMCP権限は、キー、チーム、エンドユーザー、エージェント、内部ユーザー、組織の6つの層の積集合で決まります。組織は上限として働きます。ドキュメントは、どの層にもリストが無い場合について「If no level has a list, the request can access every MCP server (open by default).(どの層にもリストが無ければ、そのリクエストはすべてのMCPサーバーへアクセスできる。既定はオープン)」と明記しています。ただしこれは現行版のドキュメントが正規のキーについて説明している既定値です。脆弱版で作られた身元の空なセッションにこの記述がそのまま当てはまるかどうかは、一次資料からは確認できませんでした。Pull Requestが影響として書いているのは allow_all_keys=True のサーバーが和集合されるところまでで、その範囲を超えて全サーバーへ届いたとする一次情報は見当たりません。権限を絞る設定を明示的に入れていない環境ほど到達範囲が広がるという話は、正規のキーが漏れた場合の被害範囲の議論として読むほうが実態に合います。
到達先として想定されるのは、そのゲートウェイに束ねている接続先のうち、上の条件に当てはまるものです。GitHub、Atlassian、Slack、Linear、社内の業務APIなどをMCPサーバーとして登録している構成であれば、ツールの列挙と呼び出しがそこへ届きます。読み出し系のツールしか登録していなければ、影響は情報の閲覧に留まります。イシューの作成、メッセージの送信、チケットの状態変更といった書き込み系が含まれていれば、影響の性質が変わります。NVDのCVSS v3.1が完全性への影響をLowと評価している点は、平均的な構成を見た評価であって、自組織の構成での影響とは別に考える必要があります。
構成を確認するときに見る場所も挙げておきます。LiteLLMのMCPゲートウェイは、config.yamlの mcp_servers ブロックにサーバーごとの接続先、トランスポート、auth_type、auth_value を書く形で設定します。auth_type に指定できる値はnone、api_key、bearer_token、basic、authorization、token、oauth2、oauth2_token_exchange、oauth2_id_jag、true_passthrough、aws_sigv4などです。今回のフォールバックが本来対象としていたのはoauth2系の設定を持つサーバーで、修正後はその条件を満たす場合にだけ動きます。裏を返せば、oauth2を1つも使っていない構成でも、修正前は同じフォールバックが発火していたことになります。
MCPという仕組みそのものが持つ攻撃面については、次の記事で整理しています。
あわせて読みたい
MCPサーバーのセキュリティ。AIエージェントとツール接続の信頼境界
KEVのdueDateとBOD 26-04の是正期限を分けて読む
CISAは2026年9月2日、7件の脆弱性をKEVカタログへ追加しました。この7件は是正期限で2つに分かれています。
| CVE | ベンダー / 製品 | dueDate | forensicTriage |
|---|---|---|---|
| CVE-2026-9586 | Sangoma / Switchvox | 2026-09-05 | Yes |
| CVE-2026-49869 | Kestra / Kestra OSS | 2026-09-05 | Yes |
| CVE-2026-82329 | JFrog / Artifactory | 2026-09-05 | Yes |
| CVE-2026-83548 | SonicWall / SMA1000 | 2026-09-05 | Yes |
| CVE-2026-83549 | SonicWall / SMA1000 | 2026-09-05 | Yes |
| CVE-2026-48710 | Kludex / Starlette | 2026-09-16 | No |
| CVE-2026-59822 | BerriAI / LiteLLM | 2026-09-16 | No |
KEVのdueDateだけを見ると、3日側の5件はいずれもTechnical Impactがtotal、14日側の2件はpartialです。ただしBOD 26-04の是正期限は、この1つの変数で決まるものではありません。ディレクティブは期限を決める変数として資産の公開状況(Publicly Exposed)、KEV収録、攻撃の自動化可能性(Automatable)、悪用後の技術的影響(Technical Impact)の4つを挙げ、期限はCVEごとではなく資産ごとに決まると定めています。KEVのエントリに載るdueDateは1つのCVEにつき1つの値なので、資産の公開状況の判定はそこに含まれていません。
Table 1: Remediation Timelinesの行を当てはめます。CVE-2026-59822はKEV収録がYes、Automatableがyes、Technical Impactがpartialです。この組み合わせで資産が公開されている場合(行2)の期限は3日、公開されていない場合(行10)は14日です。KEVに載っている2026-09-16は後者に対応する値であり、インターネットから到達できるLiteLLMを持っている組織にとっての期限ではありません。KEVのrequiredActionも「Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.(各資産のインターネット露出を評価し、BOD 26-04の適用を確かめる責任は利用側にある)」と書いています。
partialという評価は「軽い」という意味でもありません。BOD 26-04の枠組みでは、攻撃がソフトウェアの挙動に対する完全な制御を与えるかどうかが分かれ目です。CVE-2026-59822で得られるのは、MCPゲートウェイの匿名セッションであって、LiteLLMプロセスやホストの掌握ではありません。CVSSでも完全性への影響がLowに置かれていることと整合します。totalとpartialの差が効くのは、3日側にforensic triageが付くかどうかという別の軸です。
BOD 26-04が拘束するのは米国の連邦文民行政機関で、日本の組織を法的に拘束するものではありません。日付の使いどころは別にあります。CISAが実際の悪用を確認したうえで収録した事実と、自動化可能と判断した事実の2つは、社内で優先度を上げるための客観的な根拠になります。逆に、KEVの14日という値を緊急度を下げる材料として使うのは筋が通りません。BOD 26-04の考え方に沿えば、外部から到達できるLiteLLMは3日側に入ります。社内説明では、KEVのdueDateより先に自組織の到達性の判定を置きます。KEVとEPSSを日々の優先度付けへ組み込む方法は、次の記事で整理しています。
あわせて読みたい
脆弱性対応の優先順位付け。CVSSだけに頼らないEPSSとCISA KEVの使い方
悪用の観測について確認できること
一次資料として確定できる悪用の事実は、CISAがKEVへ収録したことと、SSVCのExploitationがactiveと記録されていることです。CISAは9月2日の告知でも、追加の根拠を実際の悪用の証拠(evidence of active exploitation)としています。
これに加えて、NVDがCVE-2026-59822の参照(Third Party Advisory)として収録しているのが、Wiz Researchが2026年8月27日に公開したハニーポットの観測記事です。この記事は本脆弱性の発見元としてWiz Researchを挙げ、トークン検証が失敗したときに要求を拒否するのではなく制限のない空の UserAPIKeyAuth() オブジェクトを返す、と機構を説明しています。そのうえで、自社のハニーポットで悪用を観測したとし、1文字のトークンを使ってモデル列挙エンドポイントを探索するリクエストを挙げています。ただし記事に掲載されているそのリクエストは GET /v1/models に Authorization: Bearer x を付けたもので、CVE-2026-59822の脆弱な処理が置かれているMCP Streamable HTTPのハンドラを通る経路ではありません。悪用を観測したというWizの記述と、掲載されているリクエストの例は、別のものとして読む必要があります。
読むときの前提を2つ添えます。1つ目は、これがハニーポット環境での観測であり、実運用環境での被害確認ではないことです。悪用の開始時期、被害件数、露出台数を示す一次情報は執筆時点で確認できませんでした。2つ目は、ランサムウェアとの関係を断定できないことです。同じ記事はランサムウェアグループとの関連付けについて外部の研究者による指摘として触れていますが、対象は複数の脆弱性を組み合わせた連鎖であって、CVE-2026-59822単体の話とは限りません。CISAのKEVもknownRansomwareCampaignUseをUnknownとしています。
観測の位置づけをもう1段整理します。CISAがExploitationをactiveと記録してKEVへ収録したことと、Automatableをyesと判定したことは、CISAが自ら公開している値です。社内で優先度を説明する根拠には、この2つを使います。ハニーポットの観測は、AIインフラ全般が自動探索の対象になっている状況を示す材料としては読めますが、掲載されているリクエストの例が当該CVEの経路を通らない以上、この脆弱性の実証やAutomatable判定の直接の証拠としては使えません。標的を選んだ攻撃が起きているかどうかも、公開されている資料からは判断できません。
同じ時期にKEVへ収録されたStarletteのCVE-2026-48710は、LiteLLMを含む下流のフレームワークに影響しうる別の脆弱性です。AIゲートウェイを運用している場合は、こちらの該当も別途確認する必要があります。
あわせて読みたい
StarletteのHostヘッダ検証不備CVE-2026-48710。request.url.pathとルーティングのずれが認可を迂回する
自組織が該当するかを確かめる手順
確認は自組織が管理する環境に限って行います。他者が運用するエンドポイントへの試行は、たとえ確認目的でも不正アクセス禁止法などに触れます。
- 1
稼働中の版を確認する
リポジトリのrequirements.txtやHelmのvaluesではなく、実際に動いているプロセスの版を見ます。pipで入れているなら pip show litellm、コンテナならデプロイ済みイメージのタグ、LiteLLM ProxyならUIのバージョン表示です。1.84.0未満であれば該当します。ステージングと本番で版が違う構成では両方を確認します。 - 2
MCPゲートウェイを使っているかを確認する
config.yamlの mcp_servers ブロック、管理UIのMCP Servers、REST APIの /v1/mcp/server のいずれかで、MCPサーバーを登録しているかを見ます。MCP機能を有効にしていない環境では、この脆弱性の経路は成立しません。ただし1.84.0未満には別の認証バイパス(CVE-2026-49468)も含まれるため、更新の判断は別に行います。 - 3
MCP系エンドポイントの到達範囲を確認する
対象は /mcp、/mcp/{server_name}、/{server_name}/mcp、そしてRESTの /mcp-rest/tools/list と /mcp-rest/tools/call です。前段のリバースプロキシやロードバランサのアクセス制御が実際にどう効いているかを、設定ファイルの読み合わせだけでなく、自組織の管理下にある位置から実際のリクエストを投げて確かめます。インターネットから到達できるのか、社内のどのセグメントから到達できるのかを書き出します。 - 4
権限設定の緩い箇所を洗い出す
allow_all_keys: true を設定しているサーバーと、MCP権限リストを持たないキーやチームを一覧します。前者は身元が空のセッションから到達しうる候補として一次資料で確認できるものです。後者は、正規のキーが持つ到達範囲がドキュメントの言う既定オープンになっていないかの確認です。あわせて require_key_mcp_access_defined の設定値を確認します。 - 5
到達可能だった期間を決める
デプロイ履歴から、1.84.0未満の版を稼働させていた期間と、その間の外部到達性を突き合わせます。この期間が、後のログ確認と資格情報ローテーションの対象範囲になります。
版番号だけを見て更新すると外す点
更新そのものは1.84.0以上へ上げるだけですが、LiteLLMには版の扱いで引っかかりやすい点が3つあります。
1つ目が命名規則の変更です。v1.84.0からLiteLLMのバージョン表記はPEP 440に従うようになり、安定版から -stable サフィックスが外れました。このリリースのDockerタグは litellm:1.84.0 であって litellm:1.84.0-stable ではありません。実際、GitHubのタグ一覧で -stable を含む最新はv1.83.14-stable.patch.3であり、1.84.0以降に -stable 付きのタグはありません。Helmのvalues、requirements.txt、Renovateの更新ルールなどで -stable を前提にピン留めしていると、更新がそこで止まります。
| 種別 | 旧表記 | 新表記(v1.84.0以降) |
|---|---|---|
| 安定版 | vX.Y.Z-stable | vX.Y.Z |
| 安定版のパッチ | vX.Y.Z-stable.patch.N | vX.Y.Z.postN |
| リリース候補 | vX.Y.ZrcN | |
| 開発版 | vX.Y.ZdevN |
リリースノートは、すべてのDockerタグがプレフィックス無しとv付きの両方で公開され(litellm:1.84.0 と litellm:v1.84.0 は同じイメージを指す)、これは命名の変更だけでリリースの頻度や安定性の保証やイメージの中身は変わらない、と明記しています。
2つ目がサポート範囲です。LiteLLMは2026年6月20日のブログで、直近4本の安定マイナーラインのみをアクティブにサポートする方針を示し、6月29日から適用しています。新しいラインがおよそ週に1本出るため、1ラインあたりの対象期間はおよそ1か月です。執筆時点でPyPI上のlitellmの最新は1.99.0、GitHubの最新リリースタグはv1.99.1です。つまり1.84.0へ上げるだけでは、すでにサポート対象外のラインに乗ることになります。更新先は、リリースノートで現行のサポート対象4ラインを確認してから選びます。
3つ目が1.84.0に含まれる破壊的変更です。リリースノートのImportant Behavior Changesには、パススルーエンドポイントが既定で auth: true になること、api_base と base_url のクライアント指定が制限され資格情報が除去されること、マスターキーでのリクエストがハッシュではなくエイリアスを伝播するようになることなどが並びます。MCP関連では、LiteLLM_MCPUserCredentials.credential_b64 への書き込みが encrypt_value_helper を経由するようになり、OAuthメタデータの探索がSSRFガードに従うようになり、static_headers が呼び出し側の extra_headers より優先されるようになりました。更新の前にこの節を読み、社内のクライアント実装が依存していないかを確認します。
更新できない間の暫定策
更新までに時間がかかる場合の手当ては、公式が案内している範囲に絞ります。GHSAのWorkaroundsが示しているのは、MCPルートを無効化するか、リバースプロキシやAPIゲートウェイで /mcp/ と関連するMCPエンドポイントへのアクセスを遮断する、という2つです。
構成側で締められる箇所もあります。公開範囲の制御としては、サーバー単位の available_on_public_internet を落とす方法と、general_settings.mcp_internal_ip_ranges を自組織の実際のレンジに合わせる方法があります。後者の既定値はRFC1918のプライベートアドレス範囲(10.0.0.0/8、172.16.0.0/12、192.168.0.0/16)にループバック(127.0.0.0/8)を加えたもので、実際の到達経路がプロキシ経由になっている環境では判定が期待どおりにならないことがあります。権限側では、require_key_mcp_access_defined: true を有効にして権限リストを持たないキーを弾く、allow_all_keys: true を棚卸しする、no-mcp-servers センチネルで明示的に全拒否にする、といった手が使えます。
ネットワーク側の手当ても並行します。管理用のポートを公開レンジから外すこと、コンテナイメージのタグを固定して :latest を使わないことは、LiteLLMの本番運用ドキュメントが挙げている項目です。
遮断を選ぶ場合は、副作用の確認を先に行います。/.well-known/ 配下はOAuthのメタデータ探索に使われる経路で、ここを一律に止めると、正規のMCP利用側でも認可サーバーの情報取得が失敗することがあります。止める範囲と、その間に業務側で使えなくなる機能を、先に洗い出しておきます。MCP機能を止めている間、社内のエージェントやツール連携がどう振る舞うかも確認しておくと、問い合わせ対応の量が変わります。
暫定策は修正の代わりにはなりません。GHSAの記述も「すぐに更新できない場合」という条件付きです。遮断や設定変更を入れた場合でも、更新の計画は同時に進めます。設定変更の内容と実施時刻を記録しておくと、更新後にどれを戻すかの判断が楽になります。
注意
遮断ルールをパスの前方一致だけで書くと取りこぼします。LiteLLMのMCPエンドポイントは /mcp や /mcp/{server_name} のほかに /{server_name}/mcp という形も持ち、後者は先頭がサーバー名です。RESTの /mcp-rest/tools/list と /mcp-rest/tools/call も別の前置きになります。同じ修正コミットでは、URLの部分一致で公開ルートを判定していた別の経路も塞がれています(CVE-2026-59822の本体はOAuth2フォールバック側の欠陥です)。遮断側で同じ種類の見落としをしないよう、実際のリクエストで到達可否を確かめてください。
接続先サービスの資格情報をローテーションする
1.84.0以上へ上げて終わりにできない理由は、MCPゲートウェイの役割にあります。この機械は、接続先サービスの資格情報を集約する場所です。身元が空のセッションからツールが呼べた期間があったなら、その期間にゲートウェイ経由で使われた可能性のある資格情報は、正当性が確認できないものとして扱うのが安全側です。
対象を整理すると次のようになります。
| 対象 | 保管場所 | 措置 |
|---|---|---|
| MCPサーバーごとの静的な資格情報 | config.yamlの auth_value(api_key、bearer_token、basic、authorization、tokenなど) | 上流サービス側で新規発行し、旧値を失効させる |
| OAuth2系のトークンとクライアントシークレット | oauth2、oauth2_token_exchange、true_passthrough などの設定と関連ストア | クライアントシークレットの再発行と、発行済みトークンの失効 |
| ユーザースコープのMCP資格情報 | DBの LiteLLM_MCPUserCredentials(1.84.0で encrypt_value_helper 経由の暗号化が入った) | 利用者ごとの再接続と旧資格情報の失効 |
| LiteLLMのマスターキーと仮想キー | 環境変数とDB | マスターキーの入れ替えと、疑わしい期間に発行された仮想キーの失効 |
順番は、影響の大きいものから決めます。書き込み権限を持つもの、課金につながるもの、データの持ち出しに使えるものを先に回します。読み出し専用のトークンは後回しにしても構いませんが、対象から外さずに一覧には載せておきます。
ローテーションで抜けやすいのが、上流側での失効です。新しいトークンを発行してconfigを差し替えても、古いトークンが上流サービスで有効なままなら、漏れていた場合の効果がありません。GitHubのPersonal Access Token、Atlassian、Slackなどは、それぞれの管理画面で旧トークンを失効させるところまで行います。あわせて、その上流側の監査ログを同じ期間で確認します。
LiteLLM自身の鍵についても注意点があります。本番運用ドキュメントは、マスターキーを sk- で始まる値として環境変数に置き、シークレットマネージャで管理してローテーションすることを推奨しています。一方でsalt keyについては、DBを使う構成では設定したうえで、モデルを追加した後には変更しないよう書かれています。salt keyを変えると保存済みの暗号化値が読めなくなるためです。マスターキーのローテーションとsalt keyの扱いを混同しないようにします。
資格情報を構成ファイルや環境変数でどう扱うかという設計の話は、次の記事で整理しています。
あわせて読みたい
シークレット管理の実務。APIキー・認証情報をハードコードせず、Vaultやマネージドサービスで守りローテーションする
MCP経由で到達しうるツールを棚卸しする
資格情報の次は、そのゲートウェイが公開しているツールの一覧です。この作業は今回の後始末であると同時に、次に同じ種類の認証不備が出たときの影響評価表にもなります。
手順は4つです。まず、登録済みのMCPサーバーを一覧します。config.yamlの mcp_servers、管理UIのMCP Servers、REST APIの /v1/mcp/server のいずれからでも取れます。次に、各サーバーが公開しているツールを列挙します。3つ目に、列挙したツールを、読み出しだけのものと、削除、送信、課金、権限変更のように取り消しの効かない操作を含むものに分けます。4つ目に、後者へのアクセスを mcp_tool_permissions でツール単位に絞れないかを検討します。
mcp_tool_permissions を使う場合の落とし穴がひとつあります。この設定はserver_idをキーにしてツール名のリストを持ちますが、config由来のサーバーIDはサーバー名と接続設定から導出されます。接続設定を変えるとIDが変わり、既存のキーやチームに設定した権限が対象を見失います。運用で設定変更が入る前提なら、server_id を明示してピン留めしておきます。
トランスポートの種類も影響の重さに関わります。stdioトランスポートで動かしているMCPサーバーは、プロキシのホスト上でプロセスとして起動します。同じLiteLLMのCVE-2026-42271は、まさにこのstdio設定をリクエストボディで受け付けていた点が問題になり、コマンド実行に至ったものでした。stdioで動かしているサーバーがある構成では、そのホスト上で何が起動しうるかを別途確認します。
棚卸しの結果は、サーバー名、トランスポート、auth_type、公開ツールの一覧、破壊的操作の有無、allow_all_keys の設定値、接続先サービスと資格情報の種類、という列を持つ表として残します。次に認証まわりの脆弱性が出たとき、影響範囲の見積もりがこの表を読むだけで済みます。
この棚卸しには、登録したままになっているサーバーを外すという効果もあります。検証のために追加したMCPサーバーが、資格情報を持ったまま本番の設定に残っている状態は珍しくありません。使っていないサーバーは、権限を絞るより先に登録そのものを削除し、上流側の資格情報も失効させます。ゲートウェイに束ねる接続先の数は、そのまま認証不備が出たときの影響範囲になります。
アクセスログで痕跡を探すときの見方
最初に押さえる性質があります。脆弱な版では、x-litellm-api-key が無く Authorization ヘッダだけがあるリクエストについて、キー検証の失敗が匿名セッションへ読み替えられていました。この条件に当てはまるリクエストは、LiteLLM側に認証エラーとして残りません。認証失敗のログが無いことは、試行が無かったことの証明にはなりません。なお、すべての認証失敗が消えるわけではなく、この条件に当てはまらない経路のエラーは通常どおり記録されます。
調査の主軸は、LiteLLMの前段に置いているリバースプロキシやロードバランサのアクセスログです。見る対象を挙げます。
- MCP系パスへのリクエストと応答コード。
/mcp、/mcp/{server_name}、/{server_name}/mcp、/mcp-rest/tools/list、/mcp-rest/tools/callへの200応答を、送信元IPと時系列で並べます。 - 想定外の送信元IP。社内のクライアントやCIランナー以外からのアクセスがあるかを見ます。
- クエリ文字列に
.well-knownを含むMCPルートへのリクエスト。公開ルート判定の取りこぼし経路にあたるため、正規の利用では現れにくい形です。 - Authorizationヘッダの値。通常のアクセスログには残りませんが、記録している環境では、極端に短いBearer値や、発行済みの仮想キーと突き合わない値を探します。Wizのハニーポット観測でも1文字のトークンによる探索が記録されています(ただし公開されている例はMCP系パスへのものではありません)。
LiteLLM側のログについては期待を絞ります。MCPツールの呼び出しがどのテーブルへどう記録されるかは公式ドキュメントに明記がなく、spend logsに必ず残ると前提を置くことはできません。実際に自環境で何が記録されているかを、正常なツール呼び出しを1件行って確かめてから調査に使います。
もうひとつ必要なのが、接続先サービス側の監査ログとの突き合わせです。MCPの仕様書も、トークンパススルーのリスクとして「下流のリソースサーバーのログには、実際にトークンを転送しているMCPサーバーではなく、別の送信元から別のアイデンティティで来たように見えるリクエストが記録されうる」と指摘しています。上流のログに呼び出し元がどう見えるかは、そのMCPサーバーへどの資格情報でつないでいるかによって変わり、LiteLLMの製品仕様として一律に決まるものではありません。自環境で正常なツール呼び出しを1件行い、上流側にどう記録されるかを先に確かめたうえで、時刻とツール名と操作対象で寄せる作業に入ります。GitHubやSlackの監査ログを、該当期間について同じ粒度で並べます。
記録が残っていなかった場合は、次に備える形に切り替えます。前段のプロキシで、リクエストパス、クエリ文字列、応答コード、送信元IP、Hostヘッダに相当する値を記録する設定へ変更し、保持期間を決めます。MCPゲートウェイのように多数の接続先を束ねる機械では、その1台のログが調査の起点になります。
CVE-2026-59822への対応と確認
- 稼働中のLiteLLMの版を実環境で確認し、1.84.0以上であることを確かめた
- 更新先の版を、リリースノートで現行のサポート対象4ラインを確認したうえで選んだ
- Dockerタグやピン留め設定に -stable サフィックスが残っていないかを確認し、PEP 440の新表記へ直した
- 1.84.0のImportant Behavior Changes(パススルーの既定auth、api_baseの制限、static_headersの優先など)を読み、社内クライアントへの影響を確認した
- すぐに更新できない期間について、MCPルートの無効化または前段での /mcp/ と関連エンドポイントの遮断を検討し、/.well-known/ を止めた場合の副作用を確認した
- available_on_public_internet、mcp_internal_ip_ranges、require_key_mcp_access_defined、allow_all_keys の設定値を棚卸しした
- config.yamlの auth_value に置いた資格情報と、OAuth2系のトークンおよびクライアントシークレットを一覧し、書き込み権限を持つものから順に再発行した
- 上流サービス(GitHub、Atlassian、Slackなど)の管理画面で旧トークンを失効させ、その期間の監査ログを確認した
- LiteLLMのマスターキーと、疑わしい期間に発行された仮想キーを入れ替えた。salt keyは変更対象から外して扱った
- 登録済みMCPサーバーと公開ツールを一覧し、破壊的操作を含むツールを区別したうえで mcp_tool_permissions での絞り込みを検討した
- config由来のサーバーIDを server_id の明示でピン留めし、接続設定の変更で権限が外れない状態にした
- 前段プロキシのアクセスログでMCP系パスへの200応答と送信元IPを確認し、記録が不足していた項目についてログ設定を見直した
トークンパススルーを禁じたMCP仕様に立ち返る
今回の欠陥を機構として言い直すと、認証が失敗したときに何を返すかという設計の問題でした。MCPの仕様書は、この領域について明確な規範を置いています。2025-11-25版のSecurity Best Practicesは、トークンパススルーを「MCPサーバーが、そのトークンがMCPサーバーへ適切に発行されたものかを検証せずにMCPクライアントから受け取り、下流のAPIへそのまま渡す」アンチパターンと定義し、認可の仕様で明示的に禁止されているとしています。緩和策として書かれているのは「MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server.(MCPサーバーは、そのMCPサーバーのために明示的に発行されたものではないトークンを受け入れてはならない)」という1文です。
LiteLLMの実装が倒れたのは、その一歩先でした。自分宛の検証に失敗したという結果を、上流向けのトークンらしいという推定に読み替え、権限を落とすのではなく身元を空にする方向へ進めていました。認証の性質は、成功したときに何を渡すかよりも、失敗したときに何を返すかで決まります。フォールバック経路を書くときは、その経路が「誰でもない利用者」を作り出していないかを見る必要があります。修正後の実装が、対象サーバーが解決できない場合も対象が空の場合もfail closedに倒したのは、この点への回答です。
同じ仕様書は、セッションの扱いについても「MCP servers that implement authorization MUST verify all inbound requests. MCP Servers MUST NOT use sessions for authentication.」と定めています。この節が想定している攻撃は、発行済みのセッションIDを盗んだり推測したりして再利用するもので、無効なBearerトークンから空の認証主体を新しく作る今回の欠陥とは機構が違います。ただし、受け取ったリクエストを毎回検証するという前段の要求は、どちらにも同じように効きます。
もうひとつ、LiteLLM側の事情も見ておきます。1.84.0は本件だけを直したリリースではありません。同じ版でCVE-2026-49468(Hostヘッダインジェクションによる認証バイパス)も修正されています。認証層が request.url.path で実効ルートを決めていたため、細工したHostヘッダによって、認証層が評価するルートとFastAPIが実際にディスパッチするルートがずれうるというものでした。さらに遡ると、1.83.0では /config/update が管理者ロールを検査していなかったCVE-2026-35029が修正されています。こちらは認証済みの利用者がプロキシ設定と環境変数を書き換えられるという内容で、CVSSはv4で8.7、v3.1で8.8です。KEVには収録されていません。
LiteLLMのKEV収録は今回で3件目です。1件目のCVE-2026-42208はSQLインジェクション、2件目のCVE-2026-42271はMCPプレビュー用エンドポイントでのコマンド実行でした。同じ製品の同じ領域で認証と入力処理の問題が続いている状況は、この種のAIゲートウェイをインターネットへ直接向けるかどうかという配置の判断に効きます。BOD 26-04が是正期限の最初の変数に資産の公開状況を置いているのも、そこが緊急度を最も大きく動かすためです。社外のクライアントから使う要件があるとしても、認証を1層だけに任せる構成にする必然性は多くありません。
AIを組み込んだ基盤に固有の攻撃面については、次の記事で整理しています。
あわせて読みたい
プロンプトインジェクションとは。AIエージェント時代の新しい攻撃と防御
出典・参考
- GitHub Security Advisory GHSA-7488-6r32-c95q: LiteLLM MCP Authentication Bypass via OAuth2 Passthrough Fallback
- NVD: CVE-2026-59822 Detail
- CVE Record CVE-2026-59822 (cve.org)
- CISA Known Exploited Vulnerabilities Catalog
- CISA Adds Seven Known Exploited Vulnerabilities to Catalog (2026-09-02)
- CISA BOD 26-04: Prioritizing Security Updates Based on Risk
- BerriAI/litellm commit 73869f0: fix(mcp) tighten public-route detection and OAuth2 fallback gating
- BerriAI/litellm commit 0a4640f: fix(mcp) don't coerce ProxyException.code with int()
- LiteLLM Release Notes v1.84.0
- MCP Permission Management | LiteLLM
- LiteLLM Proxy: Production Setup
- MCP Specification 2025-11-25: Security Best Practices
関連する記事
MCPサーバーのセキュリティ。AIエージェントとツール接続の信頼境界
AIエージェントを外部ツールにつなぐMCPサーバーの攻撃面を、ツールポイズニングや間接プロンプトインジェクション、過剰な権限とトークンの扱い、信頼できないサーバーとrug pullに整理し、利用者と開発者と組織の防御を公式仕様をもとに解説します。
StarletteのHostヘッダ検証不備CVE-2026-48710。request.url.pathとルーティングのずれが認可を迂回する
Starletteの通称BadHost(CVE-2026-48710)を一次情報で整理します。Hostヘッダを検証せずにURLを再構築していたため、request.url.pathがルーティングの実パスと食い違い、パス前方一致の認可ミドルウェアが迂回されます。KEV追加の事実、影響範囲、1.0.1の修正内容、暫定回避策、ログの見方をまとめます。
脆弱性対応の優先順位付け。CVSSだけに頼らないEPSSとCISA KEVの使い方
毎月大量に出るパッチを全部当てるのは不可能です。実際に悪用されている脆弱性(CISA KEV)と悪用予測スコア(EPSS)、深刻度(CVSS)を組み合わせたリスクベースの優先度付けを、優先度マトリクスと運用ステップ付きで実務担当者向けに解説します。


