MLflowにリモートコード実行の脆弱性、3.17.0で修正
MLflowのサーバーに、外部から任意のコードを実行されるおそれのある脆弱性が見つかりました。3.12.0rc0以上3.17.0未満を共有サーバーとして運用している組織が対象で、3.17.0への更新が修正になります。認証を有効にしていない環境を優先して確認してください。
急ぎ度: 早めに
CVSS v3は9.8で重大度はcriticalですが、KEVへの掲載は確認されておらず、サーバープロセスが許可パッケージに書き込める構成が前提になるため、修正版の3.17.0が出ている今のうちに計画的ではなく早めに更新する段階と見ています。
関係があるか
MLflowのサーバーを社内やクラウド上で共有運用し、チームで実験やトレースを記録している組織が対象です。認証を有効にしていないサーバーや、広いネットワークから到達できるサーバーは、とくに影響を受けやすい構成です。
| 製品 | 影響を受ける版 | 直った版 |
|---|---|---|
| MLflow(PyPIのmlflow) | 3.12.0rc0以上3.17.0未満 | 3.17.0 |
確かめ方
- 1サーバーを動かしている環境で
pip show mlflowを実行し、Versionが3.12.0rc0以上3.17.0未満かを確認します。コンテナで運用している場合は、イメージに入っているmlflowの版を調べます。 - 2サーバーの起動設定を見て、認証(basic-auth)を有効にしているかを確認します。無効なら、認証なしで悪用できる構成に当たります。
- 3サーバーがどのネットワークから到達できるか、ファイアウォールやロードバランサーの設定で確認します。
- 4MLflowのサーバープロセスを動かしているユーザーが、許可されたサードパーティ製スコアラーのパッケージに書き込めるかを、ファイルの権限で確認します。書き込めない構成なら、悪用の前提が1つ崩れます。
何が起きたか
MLflowのサーバー上で、攻撃者が用意したPythonのコードを実行されるおそれがある脆弱性です。3.12.0rc0から3.17.0の手前までの版が影響を受け、3.17.0で修正されました。
原因は、サードパーティ製スコアラーを読み込む処理にあります。スコアラーは、生成AIの出力などを評価するための部品です。mlflow/genai/scorers/base.pyの処理は、許可されたモジュールの名前空間そのものだけでなく、その配下にあるモジュールまで、リクエストで指定されたとおりに受け入れていました。
Scorer.model_validate_json() は、指定されたモジュールを読み込んでクラスを生成します。この処理はトレースの処理より前に走るため、読み込まれたコードはそこで実行されます。分類はCWE-94(コード・インジェクション)とCWE-470(外部入力によるクラスやコードの選択)です。
攻撃の流れ
-
1
到達する
MLflowサーバーのAPIに、ネットワーク経由でアクセスできる状態になります。
-
2
コードを置く
成果物(artifact)のAPIを使い、許可された名前空間の下にPythonモジュールを置きます。
-
3
読み込ませる
置いたモジュールとクラスを、スコアラーの実行リクエストで指定します。
-
4
コード実行
サーバーがそのモジュールを読み込み、クラスを生成した時点で、サーバー上でコードが動きます。
どう悪用されるか
ネットワーク越しに悪用でき、利用者の操作は要りません。認証を無効にしているサーバーでは、資格情報なしで成立します。basic-authを有効にしているサーバーでは、実験とrunを作成し、成果物をアップロードできる権限を持つアカウントが必要です。
どちらの構成でも、MLflowのサーバープロセスが、許可されたスコアラーのパッケージに書き込める必要があります。書き込めない構成では、この前提を満たしません。
悪用されると、サーバープロセスの権限でコードが実行されます。CVSSの機密性・完全性・可用性がいずれも高と評価されているとおり、保存されている実験データやモデル、接続先の認証情報の漏えい、データの改ざん、サービス停止が想定されます。
今すぐやること
-
1
使っている版を洗い出す
開発用、検証用、本番用を含め、MLflowのサーバーをすべて把握します。3.12.0rc0以上3.17.0未満が稼働していないかを確認してください。
pip show mlflow -
2
3.17.0に更新する
該当する環境は、修正版の3.17.0以降に更新します。コンテナ運用ではイメージを作り直して入れ替えます。米国の政府機関向けのKEVの期限は設定されていないので、社内の変更手続きに沿って進められます。ただ、認証なしで広く公開しているサーバーは先に対応します。
-
3
認証とネットワークの設定を見直す
認証を無効にしているサーバーは、認証を有効にするか、到達できるネットワークを必要な範囲に絞ります。更新の前後どちらでも実施できます。
-
4
書き込み権限を確認する
MLflowのサーバープロセスを動かすユーザーに、スコアラーのパッケージへの書き込み権限が不要に付いていないかを見直し、不要なら外します。
-
5
成果物の保存先を点検する
更新までに外部から到達できる状態だったサーバーは、成果物の保存先やスコアラーのパッケージ配下に、身に覚えのないPythonファイルがないかを調べます。見つかった場合は、サーバーの権限で実行された可能性があるため、インシデントとして扱います。
すぐ更新できないとき
すぐに更新できないときは、認証を有効にしたうえで、MLflowサーバーに到達できるネットワークを信頼できる範囲に絞ります。あわせて、サーバープロセスのユーザーから、許可されたスコアラーのパッケージへの書き込み権限を外します。悪用にはこの書き込み権限が必要なので、有効な一時的な対策になりえます。ただし、これらは修正の代わりにはならないため、更新までの暫定措置としてください。
背景
MLflowは、実験の記録、モデルの管理、生成AIアプリのトレースや評価をまとめて扱うオープンソースの基盤です。チームで1台のサーバーを共有し、学習データへの接続情報、モデルの成果物、評価結果が集まりやすい場所なので、サーバー上でコードが動くと影響が広がりやすくなります。
今回の対象は、評価用のスコアラーを外部のクラスとして読み込む仕組みです。名前で指定されたクラスを読み込む処理は、読み込んだ時点でコードが動くため、読み込める範囲を許可リストで限る設計になっていました。今回の問題は、その許可が名前空間の配下まで広がっていた点にあります。さらに、成果物のアップロードという通常の機能で、その配下にファイルを置ける構成が重なっていました。
よくある質問
Q.複数のサーバーがある場合、どれから更新すればよいですか。
まだ分かっていないこと
- 実際の攻撃での悪用が確認されているかどうかは、公表されていません。続報は、MLflowのGitHubのセキュリティアドバイザリ(GHSA-26p8-2jq9-3vq9)と3.17.0のリリースノートで確認できます。
- スコアラーのパッケージが書き込み可能になりやすい導入形態(pipでの導入、公式のコンテナイメージなど)は、公表されていません。自社の環境が当てはまるかは、サーバープロセスの権限を実際に確認して判断してください。
この記事は、取得元の公開情報をもとに生成 AI で作成しています。誤りを含むことがあります。対応を決める前に、下の原文と参照先を確認してください。
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 直った版 |
|---|---|---|---|
| mlflow | mlflow | — | — |
| pip | mlflow |
3.17.0 未満 |
3.17.0 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
Summary
MLflow 3.12.0 introduced registration and deserialization support for third-party scorers in OSS MLflow. During scorer deserialization, the server accepts a request-controlled Python module path beneath one of four allowed package prefixes, imports that module, obtains a request-controlled class, and instantiates it synchronously.
An HTTP caller can combine this behavior with MLflow's built-in experiment, run, and artifact-upload endpoints:
- Create an experiment whose local artifact location points to a writable allowed scorer package.
- Create a run, causing MLflow to allocate
//artifacts/. - Upload a Python module into that run artifact directory.
- Submit a serialized third-party scorer whose module path resolves to the uploaded file.
- Trigger server-side import and class construction through
/ajax-api/3.0/mlflow/scorer/invoke.
On the default no-auth server using the official MLflow v3.14.0 image, this produces unauthenticated arbitrary Python code execution with the privileges of the MLflow server process. The reproduced image runs the process as uid 0 and permits writes to its installed Python package tree.
The attached proof of concept is intentionally harmless. The uploaded constructor performs one action only: it writes a random marker beside its own uploaded run artifact. The marker is then downloaded through MLflow's run-artifact endpoint and checked for an exact match.
Technical details
1. The allow-list accepts attacker-created…
出典: CVE.org (CVE Program・cvelistV5) NVD GitHub Advisory
参照URL
- web github.com
- web github.com
- web github.com
- web github.com
- web github.com