Cloudanix VulnDB

CVE-2026-4137

High · 7.8

CVSS

7.8

EPSS

0.2%

Published

May 18, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A local user on a shared machine or shared storage system could alter temporary MLflow model files so that another user’s model-loading process runs the attacker’s code.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Low
Impact
Remote Code Execution
Component
Library
Class
Misconfiguration
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

MLflow versions before 3.11.0 create temporary directories used during model artifact download and loading with overly permissive filesystem modes: world-writable 0777 for NFS temporary directories and group-writable 0770 for model download temporary directories. On shared hosts or shared NFS-backed storage, a local low-privileged user can modify files placed in these directories before MLflow deserializes them. Because MLflow model artifacts may include cloudpickle-serialized Python objects, tampering with those artifacts can cause arbitrary Python code execution when cloudpickle.load() processes the malicious object. The resulting code runs with the privileges of the MLflow process, job, notebook, or model-serving runtime that loads the artifact.

Why it matters to the business

Organizations running MLflow on shared compute, multi-user workstations, shared NFS mounts, or managed notebook/model platforms may allow one local user or workload to compromise another user’s model-loading process. Successful exploitation can lead to theft of credentials and model artifacts, manipulation of ML experiments or production models, lateral movement through service credentials, and disruption of ML training or serving pipelines. The risk is highest where multiple users share the same filesystem namespace, especially NFS-based deployments such as environments where NFS is enabled by default. The issue is not currently listed in CISA KEV, has no known ransomware association, and has a low EPSS score, but the CVSS impact is high because exploitation can result in full confidentiality, integrity, and availability compromise of the affected MLflow runtime.

How an attack unfolds

An attacker first needs local access to the same host, container node, notebook environment, or shared NFS filesystem used by an MLflow workload. The attacker identifies MLflow-created temporary directories with overly permissive permissions. Because the directories are writable by other local users or group members, the attacker watches for model download or load activity and then replaces, modifies, or plants model artifact files, including cloudpickle-serialized objects. When a legitimate MLflow process later loads the tampered model artifact, cloudpickle.load() deserializes attacker-controlled content. Deserialization executes the embedded Python payload in the context of the victim MLflow process, giving the attacker the ability to run commands, read secrets available to that process, alter model outputs, or disrupt the workload.

How to fix it

Upgrade MLflow to version 3.11.0 or later, where the insecure temporary-directory permission behavior is corrected. If immediate upgrade is not possible, reduce exposure by ensuring MLflow temporary directories are private to the executing user or service account, setting restrictive umask values such as 077, configuring TMPDIR or equivalent temporary-directory settings to point to per-user non-shared directories, and avoiding shared world-writable NFS paths for model download and loading workflows. Restrict shell or notebook access on systems that run privileged MLflow jobs, separate users and workloads by container, VM, or cluster boundary, and ensure shared storage permissions prevent untrusted users from modifying another workload’s temporary files. Consider mounting temporary storage with noexec where operationally feasible, though this should be treated as defense in depth and not a complete fix because Python deserialization can still execute interpreter-level code.

How to confirm the fix worked

Confirm the installed MLflow version is 3.11.0 or later using package inventory, pip show mlflow, python -c 'import mlflow; print(mlflow.__version__)', container image manifests, or dependency lockfiles. On systems that run MLflow workloads, inspect temporary directories used by MLflow and verify they are not world-writable and are not writable by untrusted group members. On Unix-like systems, use commands such as find /tmp /var/tmp /mnt -type d -name '*mlflow*' -perm -0002 -ls to identify world-writable MLflow-related directories, and review NFS-backed paths separately. Exercise a representative model download/load workflow after patching and confirm newly created temporary directories have restrictive ownership and permissions. Also validate that service accounts, notebook users, and batch jobs do not share writable temporary directories unless all members are equally trusted.

Typical attack path

  1. Obtain low-privileged local access to a system, notebook cluster, shared ML platform, or NFS mount used by MLflow.
  2. Identify MLflow temporary directories created with world-writable or group-writable permissions.
  3. Monitor the temporary directory for model artifact download or loading activity.
  4. Modify or replace a serialized model artifact, such as a cloudpickle-backed Python object, before the victim process deserializes it.
  5. Wait for MLflow to load the artifact through cloudpickle.load().
  6. Execute arbitrary code under the privileges of the MLflow job, notebook, tracking process, or model-serving runtime.
  7. Use the gained execution context to access credentials, alter models or data, pivot to connected systems, or disrupt ML operations.

How to detect it

To determine whether exploitation already occurred, review host, NFS, and MLflow activity for evidence that a user or process modified MLflow temporary files owned by another user shortly before model loading. Useful sources include Linux auditd logs, EDR file modification telemetry, NFS server access logs, shell history, process accounting, notebook command history, MLflow tracking/server logs, model-serving logs, and container runtime logs. Look for world-writable or group-writable MLflow temporary directories, unexpected ownership changes, chmod/chown operations on MLflow temp paths, and writes to serialized model artifacts immediately before calls that load pyfunc or cloudpickle-backed models. Investigate unusual child processes spawned by Python or MLflow runtimes, such as shells, curl/wget, netcat, python one-liners, or commands that read secrets. Review suspicious model artifact files for pickle payload patterns that import os, subprocess, socket, builtins, eval, exec, or use __reduce__ methods. Because there are no public threat actors, KEV listing, or mature public exploit details indicated for this vulnerability, detection should focus on local tampering behavior and anomalous process execution rather than fixed network indicators.

  • drwxrwxrwx *mlflow*
  • chmod 777 *mlflow*
  • chmod -R 777 *mlflow*
  • chmod 770 *mlflow*
  • chown *mlflow*
  • cloudpickle.load(
  • mlflow.pyfunc.load_model
  • /tmp/mlflow
  • /var/tmp/mlflow
  • /mnt/*/mlflow
  • /dbfs/*mlflow*
  • python -c *cloudpickle*
  • python -c *pickle*
  • __reduce__
  • os.system
  • subprocess.Popen
  • /bin/sh -c
  • /bin/bash -c
  • curl http
  • wget http
  • nc -e
  • netcat -e

What your security team should do

  • Prioritize upgrading all MLflow installations to 3.11.0 or later, especially shared NFS, notebook, training, and model-serving environments.
  • Inventory MLflow usage across developer workstations, CI/CD runners, model-training clusters, notebook platforms, and production serving images because MLflow may be embedded as a Python dependency.
  • Immediately audit shared NFS and temporary paths for MLflow-related directories with 0777, group-writable, or unexpected ownership settings.
  • Restrict local interactive access to hosts and clusters that run MLflow jobs until patching is complete.
  • Configure MLflow workloads to use per-user or per-service-account temporary directories with restrictive permissions.
  • Monitor for non-owner writes to MLflow temporary directories and model artifact paths, particularly immediately before model load events.
  • Treat suspicious tampering of pickle, cloudpickle, or MLmodel artifacts as potential code execution and rotate credentials accessible to the affected MLflow runtime if compromise is suspected.
  • Add secure filesystem-permission checks for MLflow temporary directories to baseline hardening and CI/CD image validation.

The record

In mlflow/mlflow versions prior to 3.11.0, the `get_or_create_nfs_tmp_dir()` function in `mlflow/utils/file_utils.py` creates temporary directories with world-writable permissions (0o777), and the `_create_model_downloading_tmp_dir()` function in `mlflow/pyfunc/__init__.py` creates directories with group-writable permissions (0o770). These insecure permissions allow local attackers to tamper with model artifacts, such as cloudpickle-serialized Python objects, and achieve arbitrary code execution when the tampered artifacts are deserialized via `cloudpickle.load()`. This vulnerability is particularly critical in environments with shared NFS mounts, such as Databricks, where NFS is enabled by default. The issue is a continuation of the vulnerability class addressed in CVE-2025-10279, which was only partially fixed.

Affected packages

Ecosystem Package Introduced Fixed

Related vulnerabilities