This is a staff badge that opens the wrong internal doors, not a burglar smashing the front window
Based on the vendor metadata you supplied, CVE-2026-4035 affects mlflow/mlflow versions before 3.11.0 and is classified under CWE-201 with a vector of AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L. That combination strongly suggests an authenticated information-disclosure flaw with some cross-scope impact: a logged-in user can likely retrieve data they should not see, and may be able to make limited unauthorized changes around that data plane. In MLflow terms, the realistic blast radius is usually the tracking / tracing / experiment metadata layer rather than full server takeover.
The vendor's CRITICAL 9.1 overstates operational reality for most enterprises. The biggest downgrade factor is PR:L: the attacker needs a valid account first, which means this is usually post-initial-access or insider abuse, not opportunistic pre-auth compromise. The second downgrade factor is deployment shape: MLflow is commonly internal, team-scoped, and fronted by a reverse proxy or VPN, which sharply limits reachable population. That said, if your traces or experiment artifacts contain prompts, secrets, model inputs, evaluation data, or regulated content, the confidentiality impact is still very real, so this lands in HIGH, not MEDIUM.
4 steps from start to impact.
Obtain any valid MLflow account
- Target runs an affected MLflow version prior to 3.11.0
- Target is deployed as a reachable MLflow tracking/tracing server
- Attacker has valid credentials or equivalent session/token material
- SSO, MFA, VPN-only exposure, and IdP conditional access cut reachable population hard
- Many MLflow deployments are single-team or non-shared, reducing attacker value
- Credential theft is a separate prerequisite stage defenders can often detect
Call the overexposed API path
curl, python requests, or a browser session, the attacker invokes the affected MLflow endpoint or workflow that returns data beyond intended authorization boundaries. The vendor vector implies low complexity and no user interaction, so once authenticated the exploit path is likely straightforward. The important practitioner takeaway is that this looks like normal app traffic from a valid user, not noisy exploit spray.- Affected endpoint is enabled in the deployed feature set
- Authorization checks are missing, incomplete, or bypassable for that workflow
- If the vulnerable feature is unused, the bug becomes inert
- Reverse proxies, custom auth wrappers, or API allowlists may accidentally narrow exposure
- Tenant/workspace isolation may still reduce visible data depending on deployment
Read sensitive experiment or trace data across scope
- Sensitive data is actually present in traces, metadata, tags, or linked records
- The compromised account lacks legitimate access but can still receive the data
- Well-sanitized logging sharply reduces the value of the disclosure
- Some shops do not store production prompts, secrets, or customer data in MLflow at all
- Sparse or short retention windows reduce usable loot
Pivot to secondary abuse
- Disclosed records contain actionable secrets, keys, URLs, or internal topology data
- Secret managers, short-lived tokens, and network segmentation reduce follow-on blast radius
- Many disclosed values may be operationally interesting but not immediately exploitable
The supporting signals.
| In-the-wild status | No public exploitation evidence found in accessible sources during this assessment, and the CVE is not KEV-listed. |
|---|---|
| PoC availability | No reliable public PoC for CVE-2026-4035 was discoverable. That lowers immediate spray-and-pray risk, although MLflow has a history of attracting offensive research. |
| EPSS | No CVE-specific EPSS result was verifiable from accessible FIRST sources at assessment time; treat EPSS as unavailable rather than assuming low. |
| KEV status | Absent from CISA KEV as of this assessment; no KEV add date applies. |
| CVSS interpretation | AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:L means network-reachable but authenticated, with high confidentiality impact and only limited direct integrity/availability impact. |
| Affected versions | Per the supplied vendor intel, all mlflow/mlflow versions before 3.11.0. |
| Fixed version | 3.11.0 is the stated fix point. I found no authoritative distro backport notice for this CVE. |
| Exposure population | Real risk requires a deployed MLflow server, not just the package in a build environment. Exposure rises if the server is multi-user, reachable over the network, and stores trace/experiment data with secrets or sensitive prompts. |
| Disclosure date | Using the intel you supplied: 2026-06-03. |
| Research quality note | Public record quality is weak: I could not verify an authoritative CVE page for CVE-2026-4035 in accessible NVD/CVE search results, so parts of the attack-shape assessment are inferred from the vendor vector, CWE, fixed-version boundary, and MLflow's documented auth model. |
noisgate verdict.
The single biggest reason this is HIGH instead of CRITICAL is the authenticated attacker requirement. This is an internal trust-boundary failure in a shared MLflow deployment, not an unauthenticated edge compromise, but the confidentiality blast radius stays meaningful because MLflow often holds prompts, traces, experiment context, and occasionally secrets.
Why this verdict
- Start at 9.1, then cut for
PR:L— requiring a valid account means the attacker is already past initial access, so this is not a mass-exploitation edge bug. - Cut again for deployment reachability — many MLflow servers are internal, VPN-gated, or reverse-proxied, so only a fraction of enterprise fleets expose a reachable target population.
- Hold at HIGH because of data sensitivity — in real MLflow estates, traces and experiment metadata can contain prompts, user content, model outputs, URLs, and sometimes credentials or tokens, making confidentiality loss materially important.
Why not higher?
I do not buy CRITICAL without pre-auth access, active exploitation, or proven code execution. The vendor vector already admits the core friction: the attacker needs privileges first, which compounds with the fact that many MLflow deployments are not broadly internet-exposed.
Why not lower?
I also would not drop this to MEDIUM by default because the confidentiality impact can be severe in AI/ML environments. A low-privilege user crossing tenant or experiment boundaries in MLflow can expose operationally sensitive data that becomes a springboard for larger compromise, even if the bug itself does not directly grant RCE.
What to do — in priority order.
- Fence MLflow behind trusted access paths — Put affected MLflow servers behind VPN, private ingress, or a reverse proxy with SSO/MFA and block direct internet reachability. For a HIGH verdict, deploy this containment within 30 days if the patch is not already in flight.
- Reduce low-privilege account sprawl — Audit local MLflow users, service accounts, default roles, and stale automation tokens; remove dormant users and tighten least privilege so a compromised low-priv account has less room to exploit the flaw. Do this within 30 days.
- Sanitize trace and experiment logging — Strip secrets, prompts with customer data, bearer tokens, cloud keys, and internal URLs from tags, trace metadata, and evaluation payloads. This directly lowers blast radius if exploitation occurs and should be enforced within 30 days.
- Watch for cross-project access anomalies — Alert on users reading experiments, traces, or metadata outside their normal workspace or service role. This is a practical detective control to stand up within 30 days while patch rollout proceeds.
- TLS alone does not help; it protects transport, not authorization logic.
- EDR alone will not reliably stop valid authenticated API reads that look like ordinary app traffic.
- Changing the server port or hiding the UI path is security theater; reachable authenticated endpoints remain reachable.
Crowdsourced verification payload.
Run this on the target host or container image where MLflow is installed. Invoke it with python3 verify_mlflow_cve_2026_4035.py or point it at a different interpreter environment with python3 verify_mlflow_cve_2026_4035.py --python /venv/bin/python; no admin privileges are required unless your Python environment is access-restricted.
#!/usr/bin/env python3
"""
verify_mlflow_cve_2026_4035.py
Best-effort local verification for CVE-2026-4035 based on the vendor-supplied
fixed version boundary (< 3.11.0 vulnerable, >= 3.11.0 patched).
Outputs exactly one of:
VULNERABLE
PATCHED
UNKNOWN
Exit codes:
0 = PATCHED
1 = VULNERABLE
2 = UNKNOWN
"""
import argparse
import os
import re
import subprocess
import sys
def parse_version(v):
if not v:
return None
m = re.findall(r"\d+", v)
if not m:
return None
parts = tuple(int(x) for x in m[:4])
while len(parts) < 4:
parts = parts + (0,)
return parts
def get_version_from_current_python():
try:
try:
from importlib.metadata import version
except ImportError:
from importlib_metadata import version # type: ignore
return version("mlflow")
except Exception:
return None
def get_version_from_other_python(python_path):
code = (
"try:\n"
" from importlib.metadata import version\n"
"except Exception:\n"
" from importlib_metadata import version\n"
"try:\n"
" print(version('mlflow'))\n"
"except Exception:\n"
" pass\n"
)
try:
out = subprocess.check_output([python_path, "-c", code], stderr=subprocess.DEVNULL, text=True, timeout=15)
out = out.strip()
return out or None
except Exception:
return None
def main():
parser = argparse.ArgumentParser(description="Check whether local MLflow install is below 3.11.0")
parser.add_argument("--python", help="Path to alternate Python interpreter to inspect")
args = parser.parse_args()
fixed = parse_version("3.11.0")
installed = None
if args.python:
installed = get_version_from_other_python(args.python)
else:
installed = get_version_from_current_python()
if not installed:
print("UNKNOWN")
return 2
parsed = parse_version(installed)
if not parsed:
print("UNKNOWN")
return 2
if parsed < fixed:
print("VULNERABLE")
return 1
print("PATCHED")
return 0
if __name__ == "__main__":
sys.exit(main())
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.