
MLflow's SSRF Bypass Was Being Scanned Within Hours — And CISA Added It to KEV Two Days Later
CVE-2026-64849 bypasses MLflow's own SSRF guard using an HTTP redirect. It reads cloud metadata, has no public exploit tool listed anywhere, and got KEV'd anyway — because someone was already watching it happen.
On August 17, 2026, MLflow published an advisory for an unauthenticated SSRF in its webhook-delivery code. Within hours, the threat-intel firm watchTowr says its honeypot network saw attackers scanning for exposed MLflow servers. Two days after that, CISA added the flaw to the Known Exploited Vulnerabilities catalog. As of this writing, our own index shows zero public exploit tools for it — no Metasploit module, no Nuclei template, no GitHub PoC. That gap between "actively exploited" and "exploit code exists" is the whole story here.
The bug: a validator that only checks the first hop
MLflow lets a server admin register webhooks that fire when models are registered or promoted, and it ships a /test endpoint to fire one on demand — unauthenticated by default, because a stock mlflow server doesn't require auth at all. Since version 3.10.0, MLflow has run every webhook URL through _validate_webhook_url(), which resolves the hostname and rejects anything that lands on a private, loopback, or link-local address. That part works.
What it doesn't do is follow through. The delivery code that actually fires the webhook request does not pass allow_redirects=False, and it re-resolves whatever hostname a redirect points to without pinning it back to the address that was validated. Point a webhook at a public server you control, pass the check, then have that server answer with an HTTP redirect to somewhere the validator would have blocked — and MLflow follows it there instead.
CVE-2026-64849 exploitation chain
- Attacker registers webhook — URL points to attacker's own public HTTPS server
- _validate_webhook_url() runs — Resolves hostname, confirms it's public — passes
- POST /api/2.0/mlflow/webhooks/{id}/test — Unauthenticated endpoint, fires the webhook on demand
- Attacker server responds 302/307/308 — Redirect target: 169.254.169.254 or another internal address
- MLflow follows redirect, no re-validation — Hostname re-resolved but not re-checked against the guard
- 302/307: read cloud metadata — Response body reflected back in the /test API response
- 307/308: blind write to internal API — POST method/body preserved — internal management endpoints
- Attacker reads IAM credentials — AWS instance-metadata IAM security-credentials path
MLflow has been here before
This is not MLflow's first SSRF, and SSRF is not even MLflow's most common critical-bug class. Our graph shows 74 CVEs against the mlflow/mlflow product, a large share of them CVSS 9.8+ path-traversal and deserialization bugs against a tool that, by design, runs with filesystem and network access on behalf of ML pipelines. A representative sample:
| CVE | Issue | CVSS | EPSS | Public exploit | In KEV |
|---|---|---|---|---|---|
| CVE-2023-6974 | Server-Side Request Forgery | 9.8 | 1.5% | No | No |
| CVE-2023-3765 | Absolute path traversal | 10.0 | 67.6% | Yes | No |
| CVE-2025-11201 | Directory-traversal → RCE via model creation | 9.8 | 27.0% | No | No |
| CVE-2026-64849 | SSRF via unvalidated redirect (this one) | 9.3 | 1.1% | No (in our index) | Yes — added 2026-08-19 |
Read that table carefully and the odd one out isn't the CVSS score — three of the four sit at 9.8 or 10.0, this one's slightly lower at 9.3 because of a Scope-Changed vector with limited integrity impact. The odd one out is the KEV column. CVE-2023-3765 has a public exploit and a 67.6% EPSS score — nearly ten times higher than this bug's — and it was never added to KEV. CVE-2026-64849 has neither, and it was added within 48 hours.
Why KEV moved on a bug with no public exploit
CVSS measures theoretical severity. EPSS estimates the probability of exploitation in the next 30 days from a model trained on population-wide signals. KEV is neither of those — it's CISA's attestation of confirmed exploitation, and it doesn't require a public exploit tool to exist, only evidence that real attackers are using the bug. That's exactly the gap this CVE sits in: watchTowr's honeypot network reported scanning for exposed MLflow instances within hours of the advisory going public, and separately reported attackers using the flaw to reach cloud metadata endpoints and pull temporary credentials — evidence CISA apparently found sufficient without anyone needing to publish working exploit code first.
Disclosure to KEV, in order
- First private reportSecurity researcher freeman-bb reports the redirect-bypass gap to MLflow privately.
- Independent public reportResearcher AUTHENSOR opens a public GitHub issue describing the same class of bypass.
- CVE assigned, advisory published, fix shippedMLflow 3.15.0 released with connection-time IP pinning; watchTowr reports scanning activity beginning within hours.
- Added to CISA KEVFederal remediation deadline set for 2026-09-02, under BOD 26-04.
The fix, and why it's structurally different
MLflow 3.15.0 doesn't just patch the redirect-following logic — it changes where the check happens. Instead of validating a URL before the request goes out (which a redirect or DNS-rebind can route around after the fact), the fix validates the IP address of every socket MLflow actually connects to, immediately after the TCP handshake completes, for the original request and every redirect hop. That connection-time check is harder to bypass than a pre-request URL validator, because it can't be fooled by anything that happens between the check and the connection — there's no gap left to race.
- Upgrade to MLflow 3.15.0 or later — this is the only complete fix; no other workaround closes the redirect gap.
- If you can't patch immediately, take exposed Tracking Servers off the public internet or put them behind an identity-aware proxy — MLflow has no built-in auth by default.
- Audit registered webhooks for URLs you don't recognize, and check proxy/application logs for redirect chains ending in 169.254.169.254, loopback, or other internal ranges.
- Rotate any cloud credentials or secrets an exposed MLflow host's IAM role could reach — assume metadata access occurred if the server was internet-facing before you patched.
- Don't stop at MLflow: any service that fetches attacker-influenced URLs and validates them once before following redirects has this exact class of bug.
CVE and KEV data current as of 2026-08-20