CVE-2026-69148
Summary
The _validate_source_run and _validate_source_model functions in mlflow/server/handlers.py verify that a model version source path is within the artifact directory of a specified run or logged model, but do not check whether the caller has READ permission on that run or model. An authenticated MLflow user can therefore reference another user's run_id in CreateModelVersion, creating a model version whose artifact URI points at the victim's artifact directory. If the calling user has MANAGE permission on the registered model (which they do after creation), they can then read arbitrary files from the victim's artifact directory via GET /model-versions/get-artifact, bypassing the experiment-level READ permission gate on GET /get-artifact.
Details
POST /api/2.0/mlflow/model-versions/create is protected: the caller must have UPDATE permission on the registered model. However, the source/run_id validation performed inside _validate_source_run only verifies path containment, not caller authorization:
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(...)
After creation, the model version's source and run_id point at the victim's artifact directory. The caller can read files from that directory via the model version artifact handler, which derives the artifact path from the stored source:
GET /model-versions/get-artifact?name=<model>&version=<v>&path=<file>
This bypass matters in deployments where experiment-level permissions are explicitly restricted -- i.e., where the default_permission is NO_PERMISSIONS or the target experimen
⚡ Watch CVE-2026-69148
Get an email if CVE-2026-69148 is added to CISA KEV, gains public exploit code, or a new advisory cites it — max one per day, one-click unsubscribe.
Exploitation outlook
- Low exploitation risk0.22% 30-day exploitation probability — currently an unlikely target, but scores change as exploit code circulates. Riskier than 12% of all EPSS-scored CVEs.
Advisory coverage (2)
External references
Embed the live status
— this badge updates automatically when the KEV or exploit status changes. How to embed it →
[](https://www.csirts.com/cve/CVE-2026-69148)