CVE-2026-64849 MLflow の SSRF 脆弱性|影響確認と対応

  • URLをコピーしました!
目次

はじめに

MLflow は、実験管理とモデルレジストリを提供する OSS として、社内の ML 基盤に組み込まれている場面が増えています。Python パッケージとして導入でき、mlflow server の一行で Tracking Server が起動するため、正式な基盤としてではなく検証用途で立てたまま残っている環境も少なくありません。

その MLflow に、認証なしで悪用できる SSRF(Server-Side Request Forgery)の脆弱性 CVE-2026-64849 が公開されました。2026 年 8 月 17 日に CVE レコードが公開され、その数時間後には実際の悪用が観測されています。8 月 19 日には CISA の Known Exploited Vulnerabilities Catalog(KEV)へ追加されました。

本脆弱性が扱いにくいのは、影響の大きさがバージョンだけでは決まらない点です。Tracking Server にどこから到達できるか、Authentication を有効にしているか、MLflow の実行環境からクラウドのメタデータサービスへ通信できるか、そこにどのような権限が付与されているか。これらの組み合わせで、読み取られる情報の範囲が変わります。

この記事でわかること
  • CVE-2026-64849 がどのような仕組みで成立し、一般的な blind SSRF と何が違うのか
  • 公式上の影響範囲と、攻撃経路が実際に成立する構成条件の違い
  • 公式情報に残るバージョン表記の差と、3.14.x を対象外と誤解しないための整理
  • 管理端末のクライアントではなく、サーバー側の MLflow バージョンを確認する方法
  • 到達性、認証、内部通信、クラウド権限まで含めた影響判定の順序
  • MLflow 3.15.0 以降への更新手順と、更新までに検討できる防御強化策
  • --allowed-hosts や CORS 設定を本 CVE の対策と誤解しないための注意
  • 実悪用を踏まえた侵害確認と、認証情報を見直す判断の目安

結論から述べます。公式上の影響範囲は MLflow 3.15.0 未満で、基本対応は 3.15.0 以降への更新です。ただし、本記事で説明する攻撃経路が実際に成立するのは、Webhook 機能を備えた 3.3.0 以降で、SQL バックエンドを利用し、かつ Webhook API へ攻撃者が到達できる構成に限られます。3.3.0 未満には Webhook 機能そのものが存在しないため、少なくとも本記事で扱う経路は成立しません。

デフォルト構成の Tracking Server では Webhook API が認証なしで利用でき、テスト応答に接続先のレスポンス本文が含まれるため、内部サービスやクラウドメタデータサービスの応答を読み取られる可能性があります。実悪用が確認されているため、更新だけで完了とはせず、Webhook API への不審なアクセスの有無と、MLflow に付与した権限の取り扱いまで確認しておく価値があります。

CVE-2026-64849 の概要と対象バージョン

本章では、脆弱性の基本情報と、実悪用および KEV 掲載の位置づけ、そして公式情報に残るバージョン表記の差を整理します。

脆弱性の基本情報

CVE レコードに記載されている内容は次のとおりです。

項目内容
CVE IDCVE-2026-64849
GHSA IDGHSA-7gwp-5pfp-969j
対象製品MLflow(PyPI パッケージ mlflow
影響バージョン(公式表記)3.15.0 未満
修正バージョン3.15.0
CVSS v3.19.3(Critical)
CVSS ベクターCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N
CWECWE-918(Server-Side Request Forgery)
CVE 公開日2026 年 8 月 17 日
CISA KEV 追加日2026 年 8 月 19 日

ベクターの PR:N(権限不要)と UI:N(利用者の操作不要)が、この脆弱性の性質を端的に示しています。攻撃者は Tracking Server に HTTP で到達できればよく、MLflow の利用者に何かをさせる必要はありません。S:C(Scope: Changed)は、MLflow 自身の権限境界を越えて別のコンポーネントへ影響が及ぶことを表しています。SSRF によって内部サービスやクラウドメタデータへ手が届く構造が、スコア 9.3 の主因です。

なお、MLflow 3.15.0 は 2026 年 7 月 31 日にリリースされており、CVE の公開より 2 週間以上前に修正が配布されていました。本記事の執筆時点で PyPI 上の最新版は 3.15.1(2026 年 8 月 3 日公開)です。

公式上の影響範囲と、攻撃経路が成立する構成条件

ここは棚卸しの精度に直結するため、2 つを分けて整理します。

公式上の影響範囲は 3.15.0 未満です。 CVE レコード、NVD、GitHub Advisory Database のいずれもこの表記であり、脆弱性管理ツールの判定もこれに従います。

一方、本記事で説明する攻撃経路が実際に成立するには、次の 3 つが揃っている必要があります。

Webhook 機能を備えたバージョンであること

モデルレジストリの Webhook は MLflow 3.3.0 で追加された機能です。

SQL バックエンドを利用していること

公式ドキュメントは、ファイルバックエンドが Webhook をサポートせず、SQL バックエンドのみが対応すると案内しています。デフォルトの SQLite(sqlite:///mlflow.db)は SQL バックエンドに該当します。

Webhook API へ攻撃者が到達できること

Tracking Server の待ち受け設定、前段のアクセス制限、Authentication の有無で変わります。

参考: MLflow CHANGELOG 3.3.0(2025-08-19)
“MLflow now supports webhooks for model registry events”
(MLflow がモデルレジストリのイベントに対する Webhook をサポートしました)
https://github.com/mlflow/mlflow/blob/master/CHANGELOG.md

したがって、3.3.0 未満のバージョンには Webhook 機能そのものが存在せず、少なくとも本記事で説明する攻撃経路は成立しません。ただし、公式の影響範囲表記が 3.15.0 未満である以上、脆弱性管理上は該当扱いとなります。また、3.3.0 未満は現在サポートの対象から外れた古いバージョンであり、本 CVE とは別の脆弱性が残っている可能性があります。「3.3.0 未満だから対応不要」という結論にはならない点に注意が必要です。

なお、Webhook URL の検証処理(_validate_webhook_url)が追加されたのは 3.10.0 です。本 CVE は、この 3.10.0 で追加された検証が十分ではなかったという位置づけになります。3.3.0 から 3.9.x にはこの検証自体が存在しないため、リダイレクトを経由しなくても内部宛の Webhook を登録できた可能性がありますが、その挙動は公式に整理されたものではなく、本記事では確認していません。いずれにしても対応は 3.15.0 以降への更新です。

実悪用の状況

実悪用については、情報源によって確度が異なるため区別して扱います。

CISA が公式に示しているのは、悪用の事実に基づいて KEV へ追加したという点です。CVE レコードに付与された CISA の SSVC 評価では、Exploitation が active、Automatable が yes とされています。被害組織や攻撃キャンペーンの詳細は、KEV エントリからは示されていません。

一方、セキュリティ企業 watchTowr は、自社のハニーポットネットワークによる観測として、CVE 採番から数時間以内にクラウド上の MLflow を狙った通信を検知したと報告しています。同社は、攻撃者がクラウドメタデータサービスへ直接到達し、認証情報やシークレットを持ち出そうとしていると説明しています。

参考: Attackers Exploit MLflow SSRF Flaw to Steal Cloud Credentials and Secrets(The Hacker News)
“exfiltrating cloud credentials and secrets”
(クラウドの認証情報とシークレットを外部へ持ち出している)
https://thehackernews.com/2026/08/attackers-exploit-mlflow-ssrf-flaw-to.html

ここで注意したいのは、この観測が「すべての環境でクラウド認証情報が窃取される」ことを意味しないという点です。実際に何が読み取られるかは、クラウドメタデータサービスの保護方式(IMDSv2 のようにトークンを要求する構成か否か)、必要な HTTP ヘッダーの有無、MLflow の実行環境に付与された権限、内部ネットワークへの到達性、アウトバウンド通信の制御状況によって変わります。自環境で何が起こり得るかは、後述の影響判定で切り分ける必要があります。

KEV 掲載を CVSS とは別の判断材料として扱う

CVSS 9.3 は「悪用された場合にどれだけ影響が大きいか」を示す指標です。これに対して KEV 掲載は「実際に悪用されている」という事実の記録であり、意味する内容が異なります。スコアが高くても悪用されていない脆弱性は多く存在する一方、KEV に載った脆弱性は、対応の順序を前に倒す根拠になります。

CVE-2026-64849 の KEV エントリでは、追加日が 2026 年 8 月 19 日、Due Date が 2026 年 9 月 2 日に設定されています。Action 欄には、ベンダーの指示に従った対処に加えて、BOD 26-04 および「Forensics Triage Requirements」への準拠が記載されています。この Due Date は米国連邦政府の行政機関(FCEB)を対象とした期限であり、日本の民間企業に直接の拘束力はありません。ただし、CISA が 2 週間という猶予を設定した事実は、優先度を判断する目安として参考になります。BOD 26-04 が KEV の位置づけをどう変えたかは、関連記事『BOD 26-04 とは』で整理しています。

公式情報に残るバージョン表記の差

本 CVE では、参照する公式情報によってバージョン表記が異なります。ここを読み違えると、影響のある環境を対象外と判断してしまう可能性があるため、整理しておきます。

情報源影響バージョンの表記修正バージョンの表記
リポジトリ側の Security Advisory ページ<= 3.13.0no
GitHub Advisory Database< 3.15.03.15.0
CVE レコード / NVD3.15.0 未満3.15.0

Advisory の本文を読むと、この差の背景が見えてきます。本文には、脆弱性が当時の最新リリースである 3.13.0 と master ブランチで確認された旨が記載されています。この Advisory が非公開で報告されたのは 2026 年 6 月 12 日であり、当時 3.13.0 が最新リリースだった状況と整合します。Advisory 上部のメタデータ表示は報告時点の情報を反映したものと考えられますが、これは編集上の推論であり、公式に説明されているものではありません。

一方、Advisory 本文の Fix セクションには修正 PR(#24258、コミット ba94952247)が明記されており、MLflow 3.15.0 のリリースノートにも同じ PR が Model Registry の修正として収録されています。CVE レコード、NVD、GitHub Advisory Database、修正 PR、リリースノートを突き合わせると、3.15.0 未満が対象で、3.15.0 以降が修正版と判断できます。

実務上の要点は 1 つです。3.14.x を対象外と判断しないことです。 3.14.0 は 2026 年 6 月 17 日に公開されており、修正 PR より前のリリースです。<= 3.13.0 という表記だけを見て 3.14.x を安全と扱うと、影響のある環境が棚卸しから漏れます。

MLflow の Webhook で SSRF が成立する仕組み

本章では、なぜ Tracking Server が攻撃者の代理として内部へ通信してしまうのかを整理します。SSRF の一般論ではなく、MLflow 固有の条件に絞って説明します。

3 つの条件が重なって成立する

Advisory では、次の 3 点が重なることで成立すると説明されています。

デフォルト構成では Webhook API が認証なし

mlflow server をそのまま起動した構成(認証なし、デフォルトの SQLite バックエンド)では、モデルレジストリの Webhook API が認証なしで公開されます。Webhook に対する認可はオプションの認証プラグイン側にあり、既定では読み込まれません。

URL 検証はしているが、検証結果を接続に固定していない

MLflow 3.10.0 で追加された _validate_webhook_url は、Webhook URL のホスト名を名前解決し、パブリック IP でなければ拒否します。既定で許可されるスキームは https のみです。ただし、ここで解決した IP アドレスは、実際の接続には引き継がれません。

配信処理がリダイレクトを追跡し、再度名前解決する

Webhook の配信処理はリダイレクトを追跡する設定になっており、リダイレクト先は再検証されません。

    つまり、入口で 1 度だけ検査し、実際に接続するときには別の宛先になり得る、という構造です。

    一般的な blind SSRF との違い

    多くの SSRF は、サーバーが内部へリクエストを送るところまでは成立しても、その応答が攻撃者に返らない blind SSRF にとどまります。本脆弱性が扱いを難しくしているのは、Webhook のテスト用エンドポイントが接続先のステータスコードとレスポンス本文を呼び出し元へ返す点です。この結果、内部サービスの応答内容そのものが読み取られる可能性があります。

    参考: Unauthenticated full-read SSRF in MLflow webhook delivery(GitHub Security Advisory)
    “Because /test reflects the response body, this is an unauthenticated full-read SSRF”
    (/test がレスポンス本文を反映するため、これは認証不要の読み取り可能な SSRF となる)
    https://github.com/mlflow/mlflow/security/advisories/GHSA-7gwp-5pfp-969j

    なお、イベント駆動で自動配信される経路でも同じ SSRF は成立しますが、そちらは応答が返らないため blind な形になります。テスト用エンドポイントを経由した場合に読み取りまで到達する、という違いです。

    攻撃経路の流れ

    成立する経路を、実行可能な手順ではなく構造として整理すると次のようになります。

    1. 外部の攻撃者が、到達可能な MLflow Tracking Server を見つける
    2. 攻撃者が管理する公開 HTTPS の URL を Webhook として登録する(この URL はパブリック IP に解決されるため入口の検証を通過する)
    3. Webhook のテストを実行させる
    4. 攻撃者側のサーバーが HTTP リダイレクトを返す、または名前解決の結果を内部アドレスへ切り替える
    5. MLflow がリダイレクト先へ接続する(内部サービスやクラウドメタデータ)
    6. テストの応答として、接続先のステータスと本文が攻撃者へ返る

    リダイレクトのステータスコードによる違い

    Advisory では、リダイレクトのステータスコードによって成立する操作が変わると説明されています。

    ステータスコード成立する操作影響の性質
    302リダイレクト先を GET で取得し、応答本文が返る内部情報の読み取り
    307 / 308元の POST メソッドとボディが維持されたまま転送される内部管理エンドポイントへの blind write

    307 / 308 の場合、Advisory はこれを blind write の経路として説明しています。元の POST メソッドとボディが維持されるため、POST で動作する内部の管理エンドポイントに対して、攻撃者が用意したボディを伴う意図しない操作が届く可能性があります。読み取り側だけを想定していると、影響範囲を狭く見積もることになります。

    DNS rebinding による TOCTOU

    リダイレクトを追跡させる経路とは別に、DNS の名前解決を利用した経路もあります。検証時の名前解決と、実際に接続するときの名前解決が独立して行われ、その間に解決結果が変わり得るためです。検査した時点(Time of Check)と使用する時点(Time of Use)がずれる、いわゆる TOCTOU の問題です。

    修正で何が変わったか

    MLflow 3.15.0 に含まれる修正では、接続時に検証を行う方式へ変更されています。Advisory によれば、追加された仕組みは、ソケットが接続した直後、TLS や HTTP のやり取りが始まる前に、接続先のピア IP アドレスをパブリック IP のルールに照らして検証します。リダイレクトのたびに新しい接続が張られるため、リダイレクト先も同じ検証を通ることになります。これにより、302 による読み取り、307 / 308 による書き込み、DNS rebinding による TOCTOU がまとめて塞がれる、という説明です。

    入口での URL 検証から、接続時の宛先検証へ移した、というのが修正の要点です。

    自環境への影響を確認する流れ

    本章では、影響の有無を判断する順序を整理します。バージョンだけで判断せず、到達性、認証、内部通信、クラウド権限まで確認することをおすすめします。

    判定の順序と条件

    順序確認項目判定の観点
    1MLflow の利用有無実験管理やモデルレジストリとして利用している
    2Tracking Server の運用形態自組織でセルフホストしている
    3サーバー側のバージョン(公式の影響範囲)3.15.0 未満なら公式上は該当
    4Webhook 機能の有無3.3.0 以降なら Webhook API が存在する。3.3.0 未満は本記事の経路の対象外
    5バックエンドストアの種別SQL バックエンド(デフォルトの SQLite を含む)なら Webhook が動作する
    6Tracking Server と Webhook API への到達性外部、社内、VPN のいずれかから到達でき、前段で /api/2.0/mlflow/webhooks 配下を制限していない
    7Authentication の有無無効。有効でも管理者資格情報が侵害されれば成立し得る
    8内部サービスやメタデータサービスへの到達性MLflow ホストからリンクローカルアドレスや内部管理系へ到達できる
    9クラウド権限や内部サービスが返す情報実行環境に IAM ロールが付与されている、または内部 HTTP サービスが応答にシークレットを含む

    順序 3 から 5 が、公式の影響範囲と実際の成立条件を切り分ける部分です。順序 3 で該当しても、順序 4 と 5 の条件を満たさない構成では、本記事で説明する攻撃経路は成立しません。ただし、脆弱性管理ツールの判定は順序 3 のみを見るため、報告上は該当として扱われます。対応の優先度を下げる根拠にはできますが、更新を見送る根拠にはならない点に注意が必要です。

    順序 2 について補足します。公式ドキュメントでは Webhook が OSS 版 MLflow の機能であり、Databricks などのマネージドサービスでは利用できない場合があると案内されています。マネージドサービスのみを利用している場合の扱いは、契約しているサービス提供元へ確認することをおすすめします。

    サーバー側のバージョンを確認する

    ここが本 CVE で最も間違えやすい箇所です。確認すべきなのは、手元の管理端末に入っている MLflow クライアントのバージョンではなく、Tracking Server として動作している環境のバージョンです。 クライアントを 3.15.1 に更新しても、サーバー側が 3.13.0 のままであれば影響は残ります。

    最も確実なのは、公式ドキュメントに記載されている /version エンドポイントを参照する方法です。

    参考: MLflow Tracking Server(MLflow 公式ドキュメント)
    “can be found by querying the /version endpoint”
    /version エンドポイントへの問い合わせで確認できる)
    https://mlflow.org/docs/latest/self-hosting/architecture/tracking-server/

    # Tracking Server が返すバージョンを確認する
    curl -s http://<tracking-server>:5000/version

    Authentication を有効にしている環境では、この問い合わせにも資格情報が必要になる場合があります。応答が得られない場合は、以下の方法を組み合わせて確認します。

    # Tracking Server が動作しているホストまたはコンテナー内で実行する
    python -m pip show mlflow
    python -c "import mlflow; print(mlflow.__version__)"
    # 実行中のコンテナー内でパッケージを確認する
    docker exec <container> python -m pip show mlflow
    
    # Kubernetes 環境ではイメージタグと実際のパッケージの両方を見る
    kubectl get deployment <name> -o jsonpath='{.spec.template.spec.containers[*].image}'
    kubectl exec deploy/<name> -- python -m pip show mlflow

    このほか、requirements.txtpyproject.toml、ロックファイル、Helm の values、Docker Compose のイメージ指定も確認対象になります。ただし、これらは意図した構成を示すものであり、稼働中の実体と一致しているとは限りません。イメージタグが latest のまま固定されていたり、コンテナー内で個別にパッケージを更新した履歴が残っていたりする環境では差が生じます。宣言側の設定と、稼働側の実体の両方を確認することをおすすめします。

    なお、pip showmlflow.__version__ は Python パッケージ管理の一般的な仕様に基づく確認方法であり、仮想環境の切り分けやインストール方式によって結果が変わります。mlflow server プロセスの起動コマンドから、どの Python 環境で動作しているかを先に特定しておくと確実です。

    Tracking Server と Webhook API への到達性を確認する

    「インターネットに公開していないため対象外」と結論づけるのは早計です。攻撃者が到達できる経路は、外部公開だけではありません。

    • 社内ネットワークの利用者、および侵害された社内端末
    • VPN 接続の利用者や、委託先からのリモートアクセス
    • 同一クラスターや同一 VPC 内の他のワークロード
    • 開発用途で立てたまま管理台帳に載っていない Tracking Server

    デフォルトの mlflow serverhttp://127.0.0.1:5000 で待ち受け、ローカルホストからの接続のみを受け付けます。ただし、Kubernetes の Pod や Docker コンテナーで動かす場合は --host 0.0.0.0 の指定が必要になるため、実際の運用環境では外部インターフェースで待ち受けている構成が一般的です。

    到達性の確認では、Ingress やロードバランサーの設定だけでなく、セキュリティグループやネットワークポリシーの実効値まで見ておくと精度が上がります。AI / ML 基盤の管理 API がネットワーク到達性でリスクを大きく左右する構図は、Ray の事例でも同様でした。詳細は関連記事『CVE-2025-62593 Ray の RCE 脆弱性』で整理しています。

    Authentication の有無で悪用条件がどう変わるか

    MLflow Authentication(mlflow server --app-name basic-auth)を有効にすると、Webhook に関する操作には管理者権限が求められます。

    参考: Webhooks(MLflow 公式ドキュメント)
    “all webhook operations (create, list, get, update, delete, and test) require admin privileges”
    (Webhook のすべての操作(作成、一覧、取得、更新、削除、テスト)には管理者権限が必要)
    https://mlflow.org/docs/latest/self-hosting/webhooks/

    これにより、認証なしで誰でも Webhook を登録してテストする、という前提は崩れます。ただし、Authentication の有効化は脆弱性の修正ではありません。 次の点が残るためです。

    • 管理者アカウントの資格情報が漏えいした場合、同じ経路が成立する
    • 公式ドキュメントには、認証機能を初めて有効にしたときに作成される既定の管理者アカウントとして admin / password1234 が記載されており、パスワードを早期に変更することが推奨されています
    • 認証情報は環境変数や ~/.mlflow/credentials に平文で保存され得るため、他の侵害と組み合わされる余地が残る

    そのため、Authentication の有効化は影響を小さくする措置として扱い、3.15.0 以降への更新を基本対応と位置づけることをおすすめします。

    内部通信とクラウド権限を確認する

    SSRF は、そのサーバーが HTTP で到達できる範囲までしか影響しません。逆に言えば、MLflow のホストから何に到達できるかが、読み取られ得る情報の範囲を決めます。

    • MLflow のホストからクラウドのメタデータサービスへ到達できるか
    • 内部の管理系サービス(データベース、キャッシュ、管理 API など)へ到達できるか
    • アウトバウンド通信が既定許可になっているか、宛先を限定しているか

    本 SSRF 単独で読み取られ得る情報の範囲

    ここは過大評価も過小評価も避けたい部分です。本脆弱性で成立するのは、MLflow が HTTP リクエストを送り、その応答本文が返ってくるという経路です。したがって、読み取りの対象になるのは次の 2 種類に絞られます。

    区分具体例本 SSRF での扱い
    メタデータサービスが発行する一時認証情報インスタンスに紐づくロールの一時的なトークンHTTP で応答が返れば読み取られ得る
    内部 HTTP サービスが応答として返すシークレット設定配信 API、管理エンドポイント、内部ダッシュボードの応答HTTP で応答が返れば読み取られ得る
    環境変数や設定ファイル内の静的キーAWS_ACCESS_KEY_ID 等の環境変数、~/.aws/credentials本 SSRF 単独では直接読み取れない

    環境変数やディスク上の資格情報ファイルは、HTTP の応答として返るものではないため、本 SSRF 単独で読み出すことはできません。これらが危険にさらされるのは、読み取った一時認証情報や内部サービスの応答を足がかりに、別の侵害が連鎖した場合です。

    一時認証情報が読み取られ得るかどうかは、メタデータサービスの保護方式にも左右されます。あらかじめ取得したトークンを HTTP ヘッダーに付けて要求する構成では、単純なリダイレクト 1 回では到達しにくくなります。自環境のメタデータサービスがどの方式で動作しているかを確認しておくと、影響の見積もりが具体的になります。

    あわせて、MLflow の実行環境にどのような権限が付与されているかを確認します。Artifact Store をクラウドストレージに置いている場合、公式ドキュメントは、資格情報が Tracking Server の初期化時に一度だけ設定され、Tracking Server にアクセスできる利用者はその権限で提供されるアーティファクトへアクセスできる、と説明しています(Artifact Stores)この設定に環境変数の静的キーを使っている場合、そのキー自体が本 SSRF で読まれるわけではありませんが、メタデータサービス経由の一時認証情報が読まれた場合に何ができてしまうかという観点では、付与した権限の広さがそのまま影響範囲になります。

    MLflow 3.15.0 以降への更新と更新までの防御強化

    本章では、基本対応となる更新の手順と、更新までの間に検討できる措置を整理します。

    更新の基本手順

    公式のアップグレードガイドが示す流れは次の 4 段階です。

    1. サーバーを停止する
    2. 環境上のパッケージバージョンを更新する
    3. データベースバックエンドを使用している場合は、スキーマのマイグレーションを実行する
    4. サーバーを再起動する

    これに、実務上必要な確認を加えると次のようになります。

    STEP
    更新対象のサーバー環境を特定する

    前章の方法で、Tracking Server がどのホスト、どのコンテナー、どの Python 環境で動作しているかを確定させます

    STEP
    バックエンド DB と設定をバックアップする

    マイグレーション前のバックアップは公式ドキュメントでも案内されています

    STEP
    Tracking Server を停止する

    公式ドキュメントは、稼働中のサーバーをそのまま更新する方式をサポートしていないと明記しています。停止時間を避けたい場合は、ロードバランサーを用いたローリング更新が案内されています

    STEP
    パッケージまたはコンテナーイメージを更新する

    STEP
    必要に応じて DB マイグレーションを実行する

    STEP
    サーバーを再起動する

    STEP
    サーバー側のバージョンと起動状態を確認する

    STEP
    MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS が有効になっていないことを確認する

    この環境変数は、更新後の 3.15.0 以降でもプライベート IP への Webhook 通信を意図的に許可します。検証環境での動作確認のために設定した値が本番環境へ持ち込まれていないか、起動時の環境変数、Deployment のマニフェスト、Helm の values、.env ファイルを確認します

    STEP
    Webhook を利用している場合は、正規の接続先への配信を確認する

      パッケージの更新と DB マイグレーションのコマンドは次のとおりです。

      # パッケージを更新する
      pip install --upgrade "mlflow>=3.15.0"
      
      # DB バックエンドを使用している場合、スキーマを更新する
      mlflow db upgrade <backend-store-url>
      # MLflow Authentication を利用している場合、認可用 DB も別途更新する
      python -m mlflow.server.auth db upgrade --url <database_url>

      マイグレーションについては、公式ドキュメントに明確な注意書きがあります。

      参考: How to Upgrade MLflow(MLflow 公式ドキュメント)
      “Schema migrations can be slow and are not guaranteed to be transactional.”
      (スキーマのマイグレーションは時間がかかる場合があり、トランザクションが保証されるものではありません)
      https://mlflow.org/docs/latest/self-hosting/migration/

      トランザクションが保証されない以上、バックアップの取得はロールバック手段そのものです。実験データやモデルレジストリの規模が大きい環境では、マイグレーションの所要時間を事前に見積もっておくと、作業計画を立てやすくなります。

      更新の順序については、まずサーバー側を更新し、クライアント側の SDK は公式の互換性方針と実環境での動作を確認したうえで更新を判断する進め方をおすすめします。公式ドキュメントによれば、Tracking Server は 1 メジャーバージョンまでの古い SDK と動作する一方、サーバーより新しい SDK には対応しない場合があります。この方針からも、サーバーを先行させる順序に整合性があります。ただし互換性は最善努力とされているため、CI やバッチから MLflow を呼び出している場合は、更新後に代表的なジョブでログ記録とモデル登録が通ることを確認しておくと安全です。

      コンテナーや Kubernetes 環境での注意

      稼働中のコンテナーに入って pip install --upgrade mlflow を実行すると、その場では新しいバージョンになります。しかし、これは恒久的な対処にはなりません。Pod が再作成されたり、コンテナーが再起動されたりすれば、元のイメージの内容に戻ります。

      コンテナー環境では、イメージ側またはマニフェスト側を更新することが必要です。

      • ベースイメージまたは Dockerfile の mlflow バージョン指定を更新し、イメージを再ビルドする
      • Kubernetes の Deployment や Helm の values に記載しているイメージタグを更新する
      • イメージタグを latest などの可変タグにしている場合は、imagePullPolicy と実際に取得されたダイジェストを確認する

      緊急の応急処置としてコンテナー内で更新する場合は、その旨を記録として残し、イメージ更新までを 1 つの対応として管理することをおすすめします。

      更新までに検討できる防御強化策

      ここで扱う内容は、MLflow 公式が本 CVE 専用の回避策として提示しているものではありません。 Advisory には Workarounds のセクションがなく、示されている対処は 3.15.0 以降への更新です。以下は、更新までの期間に攻撃面を小さくするための、本記事としての提案です。いずれも修正版への更新を不要にするものではありません。

      • Tracking Server の外部公開を一時的に停止する
      • 接続元を管理ネットワークや必要な利用者に限定する
      • リバースプロキシや API Gateway で /api/2.0/mlflow/webhooks 配下へのアクセスを制限する
      • MLflow Authentication を有効にし、既定の管理者パスワードを変更する
      • MLflow のホストから、クラウドメタデータサービスや管理系ネットワークへのアウトバウンド通信を制限する
      • MLflow に付与したクラウド権限を、業務上必要な範囲まで絞る
      • 利用していない Webhook 設定を無効化または削除する

      このうち、アウトバウンド通信の制限とクラウド権限の最小化は、本 CVE を修正したあとも有効に働きます。更新のついでに見直しておくと、次の同種の脆弱性に対する備えにもなります。

      本 CVE の対策にならない設定

      紛らわしい設定がいくつかあるため、区別を明記します。

      設定本来の役割本 CVE との関係
      --allowed-hosts(MLflow 3.5.0 以降)受信リクエストの Host ヘッダーを検証し、Tracking Server に対する DNS rebinding を防ぐ受信側の保護であり、Webhook から外向きに発生する通信には作用しない
      --cors-allowed-originsどの Web アプリケーションから API へアクセスできるかを制御するブラウザー経由のアクセス制御であり、本 CVE の修正にはならない
      MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS=trueWebhook からプライベート IP への通信を許可するガードを意図的に外す設定であり、暫定対策として使う性質のものではない

      特に --allowed-hosts は、DNS rebinding という同じ用語が出てくるため混同しやすい箇所です。Tracking Server が受け取るリクエストの Host ヘッダーを検証する機能であり、Tracking Server が Webhook として送り出す通信の宛先を検証するものではありません。今回の修正が接続時のピア IP 検証である点と対比すると、役割の違いが整理できます。

      MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS については、もう一段の注意が必要です。この設定は 3.15.0 以降でもプライベート IP への通信を許可し続けます。更新によって追加された接続時のピア IP 検証は、この設定が有効な環境では期待どおりに働きません。ローカル環境での Webhook 検証のために一時的に設定し、そのままイメージやマニフェストへ残ってしまう構成は起こり得ます。更新の完了確認とあわせて、本番環境で有効になっていないことを確認しておくことをおすすめします。

      更新後に必要な侵害確認と認証情報の見直し

      実悪用が確認されている以上、更新をもって対応完了とはしにくい状況です。本章では、更新後に確認しておきたい観点を整理します。なお、以下で挙げる確認内容は一次情報から確認できたエンドポイントと一般的なログ運用に基づくものであり、特定の製品のイベント名を前提としたものではありません。

      Webhook API へのアクセスを確認する

      リバースプロキシ、Ingress、WAF、ロードバランサーのアクセスログを対象に、次の観点で検索します。

      # Webhook の作成
      POST /api/2.0/mlflow/webhooks
      
      # Webhook のテスト実行
      POST /api/2.0/mlflow/webhooks/<webhook_id>/test
      
      # Webhook の削除(痕跡の消去に使われ得る)
      DELETE /api/2.0/mlflow/webhooks/<webhook_id>

      正規の運用で Webhook を使っていない環境であれば、これらのパスへのアクセスが記録されていること自体が確認の起点になります。Webhook を運用している環境では、変更管理の記録と突き合わせて、想定外の作成やテスト実行がないかを確認します。

      DELETE の確認は特に重要です。攻撃者が登録した Webhook をテスト実行後に削除していれば、現在の一覧には何も残りません。作成と削除が短時間で対になって記録されている、あるいは変更管理に対応する記録がない削除が存在する、といったパターンは調査の手がかりになります。作成、テスト、削除の 3 つを時系列で並べて確認することをおすすめします。

      Tracking Server 自身のアクセスログを取得していない構成も少なくありません。前段のプロキシ側にしかログがない場合は、その保存期間が実質的な調査可能範囲になります。

      登録されている Webhook を棚卸しする

      現在登録されている Webhook の一覧を取得し、承認済みの設定と照合します。一覧取得は次のエンドポイントです。

      GET /api/2.0/mlflow/webhooks

      身に覚えのない宛先が登録されていれば、それ自体が調査の対象になります。ただし、前述のとおり、一覧に不審な設定がないことをもって侵害なしと判断することはできません。現在の登録状況は、あくまでアクセスログと組み合わせて読む材料です。

      アウトバウンド通信と内部サービス側を確認する

      MLflow のホストを起点とした通信を確認します。

      • クラウドのメタデータサービス宛(リンクローカルアドレス)への HTTP 通信
      • 内部の管理系サービス宛の、業務上想定していない通信
      • ループバックアドレス宛の、通常の動作では発生しない接続

      307 / 308 による blind write の経路も考慮すると、MLflow 側のログだけでなく、内部サービス側の受信ログも確認対象になります。POST で動作する管理エンドポイントを持つコンポーネントがある場合は、そちらの操作履歴も見ておく価値があります。

      認証情報の見直しは種別ごとに分けて判断する

      判断の目安として、次の条件が揃うほど、何らかの情報が読み取られた可能性が高まります。

      1. サーバー側のバージョンが 3.15.0 未満のまま、攻撃者が到達可能な状態で稼働していた
      2. Webhook 機能が有効なバージョン(3.3.0 以降)で、SQL バックエンドを利用していた
      3. Authentication が無効、または Webhook API を前段で制限していなかった
      4. MLflow のホストからクラウドメタデータサービスや内部 HTTP サービスへ到達できる構成だった
      5. Webhook API へのアクセスログを取得していない、または保存期間を超えている

      そのうえで、対応は認証情報の種別によって異なります。前章で整理したとおり、本 SSRF 単独で読み取られ得るのは HTTP の応答として返る情報に限られるためです。

      種別本 SSRF での読み取り可否取るべき対応
      メタデータサービスが発行する一時認証情報到達できれば読み取られ得るセッションの失効、ロールの権限見直し、インスタンスやタスクの再作成
      内部 HTTP サービスが応答に含むシークレット到達できれば読み取られ得る当該サービス側でのシークレット再発行
      環境変数や設定ファイル内の静的キー本 SSRF 単独では直接読み取れない一次的なローテーション対象にはならない。連鎖侵害の痕跡が見つかった場合に実施

      一時認証情報については、ローテーションという言い方よりも、発行済みセッションの失効と、付与している権限そのものの見直しが実務上の対応になります。有効期限が短いとはいえ、読み取られた時点から失効までの間は利用され得るため、クラウド側の監査ログで、MLflow に付与した権限が MLflow の稼働する IP アドレスや通常の利用時間帯とは異なる形で使われていないかを確認します。

      静的キーについては、本 SSRF が直接の読み取り経路にならない以上、本件だけを理由に一斉ローテーションを実施する必要性は高くありません。ただし、一時認証情報の悪用や内部サービスへの侵入の痕跡が確認された場合は、そこから静的キーへ到達された可能性を評価し、ローテーションを検討します。

      ログに痕跡が見つからないことは、侵害がなかったことの証明にはなりません。攻撃者が Webhook を削除した場合や、そもそも必要なログを取得していなかった場合があるためです。影響を否定できない場合は、ローテーションや権限見直しの手間と、認証情報が使われ続けるリスクを比べたうえで判断する形になります。

      まとめ

      CVE-2026-64849 は、MLflow の Webhook 配信処理における SSRF の脆弱性です。公式上の影響範囲は 3.15.0 未満ですが、本記事で説明した攻撃経路が成立するのは、Webhook 機能を備えた 3.3.0 以降で SQL バックエンドを利用し、Webhook API へ到達できる構成に限られます。実悪用が確認され KEV へ掲載された点は、CVSS 9.3 という数値とは別に優先度を判断する材料になります。

      • 公式上の影響範囲は 3.15.0 未満で、基本対応は 3.15.0 以降への更新
      • 攻撃経路が成立するのは 3.3.0 以降かつ SQL バックエンドの構成
      • Advisory の表記と CVE レコードに差があり、3.14.x も対象範囲
      • 確認するのはクライアントではなく Tracking Server 側のバージョン
      • Authentication の有効化は更新の代替にならない緩和策
      • プライベート IP 許可の環境変数は更新後も制限を解除する設定
      • 更新後も Webhook の作成・テスト・削除のログ確認と権限見直しが必要

      以上、最後までお読みいただきありがとうございました。

      よかったらシェアしてね!
      • URLをコピーしました!

      この記事を書いた人

      関西を拠点に活動する、現役インフラエンジニア。経験20年超。

      大手通信キャリアにて、中〜大規模インフラ(ネットワーク・サーバ・クラウド・セキュリティ)の設計・構築およびプロジェクトマネジメントに従事。現場で直面した技術課題への対処や、最新の脆弱性情報への実務対応を、一次情報として発信しています。

      保有資格
      CCIE Lifetime Emeritus(取得から20年以上)/ VCAP-DCA / Azure Solutions Architect Expert

      ▶ 運営者プロフィール(詳細)

      目次