MLflow Vulnerability Report
September 8, 2026

Arbitrary Code Execution via Attacker-Controlled loader_module
CVE Number
CVE-2026-79721
Summary
A malicious MLflow PyFunc model artifact can cause arbitrary code execution when loaded using mlflow.pyfunc.load_model(). The model's MLmodel configuration controls the python_function.loader_module and code settings. During model loading, MLflow adds the configured code directory to sys.path and imports the specified loader module. An attacker who controls the model artifact can therefore cause Python code contained in the artifact to execute with the privileges of the process loading the model.
Products Impacted
This vulnerability is present starting 0.0.1.
CVSS Score: 8.6
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
CWE Categorization
CWE-829: Inclusion of Functionality from Untrusted Control Sphere
Details
Mlflow.pyfunc.load_model resolves the supplied model URI to a local model directory, downloading the referenced artifacts when necessary. It then reads the model's MLmodel file and extracts the python_function flavor configuration.
If the flavor specifies a code path, MLflow adds that path to sys.path before importing the module specified by loader_module.
https://github.com/mlflow/mlflow/blob/8a774946bc19b59cecf3c54a733ebab52aa766f5/mlflow/utils/model_utils.py#L314-L315
def _add_code_to_system_path(code_path):
sys.path = [code_path] + sys.pathBoth the code and loader_module values originate from the model's MLmodel configuration. By placing the configured code directory at the beginning of sys.path, MLflow allows the subsequent module import to resolve against files contained within the model artifact.
Python executes module-level statements when a module is imported. Consequently, attacker-controlled code executes before MLflow invokes the module's _load_pyfunc() function.
The same execution primitive can also be delivered through remotely hosted MLflow artifacts. When a runs:/ or models:/ URI is supplied, mlflow.pyfunc.load_model() resolves and downloads the referenced model artifacts before processing the MLmodel configuration.
An attacker who can publish or modify a model artifact that is later loaded by another user can therefore deliver both the malicious MLmodel configuration and the corresponding Python module remotely.
# evil_model/MLmodel
artifact_path: model
flavors:
python_function:
loader_module: payload
code: "."
python_version: "3.9.0"
env:
conda: conda.yaml
virtualenv: python_env.yaml
mlflow_version: 3.1.4
model_uuid: deadbeef-dead-beef-dead-beefdeadbeef
run_id: deadbeef-dead-beef-dead-beefdeadbeef# evil_model/payload.py
print("PWNED!")
def _load_pyfunc(data_path, model_config=None): ...Loading the crafted model causes payload.py to be imported. The module-level print() executes during import, causing `PWNED!` to be printed before _load_pyfunc() is invoked.
# poc.py
import mlflow.pyfunc
mlflow.pyfunc.load_model('./evil_model')
Project URL:
https://github.com/mlflow/mlflow
RESEARCHER: Esteban Tonglet, Security Researcher, HiddenLayer
Related SAI Security Advisory
September 8, 2026
MLflow Vulnerability Report
A malicious MLflow model artifact can cause code execution during mlflow.pyfunc.load_model. The loader reads import settings from the model’s MLmodel file and imports the specified module without an allowlist or trust check, allowing attacker-controlled code in the artifact to run on the loading machine.
August 27, 2026
Netron Vulnerability Report
Reflected XSS in Netron versions <=9.1.2 on desktop application through unsanitized node names allows an attacker to hide certain nodes, perform port scanning or abuse a Chrome n-day to achieve Remote Code Execution.