← Back to Feed CACHED · 2026-08-18 22:21:36 · CACHE_KEY CVE-2026-64849
CVE-2026-64849 · CWE-918 · Disclosed 2026-08-17

MLflow is an open source AI engineering platform for agents

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

It's like leaving a signed blank check on the front desk — anyone walking by can cash it at any bank in the building

CVE-2026-64849 is an unauthenticated Server-Side Request Forgery (SSRF) in MLflow's webhook test endpoint (POST /api/2.0/mlflow/webhooks/{id}/test). The _validate_webhook_url() function in mlflow/utils/validation.py resolves the supplied hostname and blocks RFC-1918 / link-local addresses, but mlflow/webhooks/delivery.py follows HTTP 3xx redirects without re-validating the destination. An attacker hosts a public URL that passes the initial check, then issues a redirect to http://169.254.169.254/latest/meta-data/iam/security-credentials/ or any internal service. The full response body is reflected back to the caller. All MLflow versions before 3.15.0 are affected; no authentication or special configuration is required.

The vendor's CRITICAL 9.3 score is accurate and, if anything, generous only in not accounting for the active exploitation. The CVSS vector (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N) correctly reflects the unauthenticated, network-reachable, cross-scope read. Because MLflow tracking servers are routinely deployed on cloud VMs and containers with attached IAM roles, the practical impact of this full-read SSRF is cloud credential theft at scale — not a theoretical internal port scan. watchTowr's honeypot network confirmed exploitation within hours of disclosure.

"Unauthenticated full-read SSRF in MLflow webhooks is being exploited in the wild to steal cloud credentials."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Discover exposed MLflow tracking server

The attacker scans for MLflow instances via Shodan, FOFA, or Censys. MLflow's default tracking UI binds to 0.0.0.0:5000 and returns distinctive response headers and HTML titles. Shodan sweeps in June 2026 counted MLflow exposure up 173% year-over-year, with thousands of instances publicly reachable.
Conditions required:
  • MLflow tracking server reachable from the internet or attacker-controlled network segment
Where this breaks in practice:
  • Organizations behind VPN/Zero-Trust overlays are not reachable
  • Some cloud deployments use ALB with authentication middleware in front
Detection/coverage: Shodan/Censys dork: http.title:"MLflow" or http.favicon.hash matching MLflow. GreyNoise tags may appear for MLflow scanning activity.
STEP 02

Prepare redirect server

The attacker sets up a lightweight HTTP server on a public IP that returns a 302 Found redirect to the target internal URL (e.g., http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>). The redirect target is chosen based on the suspected cloud provider. This is trivial — a single Python one-liner or Nginx rewrite rule suffices. DNS rebinding is an alternative bypass if redirects are blocked.
Conditions required:
  • Attacker controls a public HTTP endpoint
Where this breaks in practice:
  • None — trivial to set up
STEP 03

Send unauthenticated webhook test request

The attacker sends POST /api/2.0/mlflow/webhooks/{id}/test with the redirect URL as the webhook target. _validate_webhook_url() resolves the attacker's public hostname, sees a public IP, and allows it. The request proceeds to delivery.py, which follows the 302 redirect to the internal/metadata endpoint without re-validation.
Conditions required:
  • No authentication required
  • Webhook test endpoint must be enabled (default)
Where this breaks in practice:
  • IMDSv2 (AWS) requires a PUT with hop-limit token — MLflow's GET/redirect flow cannot satisfy this, blocking credential retrieval on IMDSv2-enforced instances
  • GCP and Azure metadata endpoints require specific headers (Metadata-Flavor: Google, Metadata: true) that may not be forwarded through the redirect
Detection/coverage: WAF rules inspecting outbound request patterns to 169.254.169.254 in request bodies. IDS signatures for SSRF payloads in POST parameters.
STEP 04

Receive reflected response with secrets

MLflow returns the internal service's response body and status code in the webhook test response JSON (response_status, response_body). On AWS IMDSv1 instances, this contains temporary IAM credentials (AccessKeyId, SecretAccessKey, Token). On other cloud providers, service account tokens or managed identity tokens may be returned, depending on metadata header requirements.
Conditions required:
  • Target internal service responds to the redirected request
  • Cloud metadata service uses IMDSv1 or does not enforce request headers
Where this breaks in practice:
  • IMDSv2 enforcement blocks this path on AWS
  • Network-level metadata firewalls (e.g., GKE Workload Identity, AWS instance metadata firewall) block access
Detection/coverage: CloudTrail / GCP Audit Logs showing metadata service access from MLflow process. Anomalous AssumeRole or token generation events from the MLflow instance's IAM role.
STEP 05

Lateral movement with stolen credentials

The attacker uses the stolen cloud credentials to access S3 buckets, RDS databases, Secrets Manager entries, or other cloud resources accessible to the MLflow instance's IAM role. ML infrastructure IAM roles are frequently over-provisioned with access to training data stores, model registries, and artifact buckets containing proprietary data.
Conditions required:
  • Stolen credentials have useful permissions
  • Credentials have not expired
Where this breaks in practice:
  • Least-privilege IAM roles limit blast radius
  • AWS GuardDuty / GCP Security Command Center may flag credential use from anomalous IPs
Detection/coverage: GuardDuty finding UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS. Cloud SIEM correlation on credential use from non-VPC source IPs.
03 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationActive. watchTowr Intel's Attacker Eye honeypot network detected exploitation attempts within hours of CVE assignment on 2026-08-18. Threat actors are scanning for exposed MLflow instances to steal cloud credentials. Not yet on CISA KEV.
Proof-of-ConceptTrivially reproducible. No named PoC repo yet, but the attack requires only a public redirect server and a single curl command. The CVE-2026-PoCs collection on GitHub is tracking 2026 disclosures. Full technical write-ups published by TheHackerWire and CyberPress.
EPSS Score0.00349 (low percentile) — EPSS has not yet caught up to the observed in-the-wild activity, likely due to the 2-day-old disclosure window.
KEV StatusNot listed as of 2026-08-19. Given active exploitation, KEV addition is plausible within days.
CVSS VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N — Unauthenticated network attack, low complexity, no user interaction, scope change (crosses from MLflow to internal network/cloud), high confidentiality impact, low integrity impact (webhook state manipulation).
Affected VersionsAll MLflow releases < 3.15.0. This includes the entire 2.x line and 3.0.0 through 3.14.x.
Fixed VersionMLflow 3.15.0 (commit ba94952, PR #24258). Fix pins the resolved IP before following redirects.
Exposure DataShodan/ARIAscout June 2026 sweep: MLflow internet exposure up 173% YoY. Thousands of instances publicly discoverable. MLflow default config binds to 0.0.0.0:5000 with no authentication.
Disclosure Date2026-08-17 (advisory published). Exploitation observed by 2026-08-18.
ReporterCredited to GitHub_M per GHSA-7gwp-5pfp-969j. Issue #24179.
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to CRITICAL (9.3/10)

The decisive factor is active in-the-wild exploitation of an unauthenticated, zero-interaction SSRF that yields cloud credentials from a component whose internet exposure is growing 173% year-over-year. MLflow's canonical deployment role as ML pipeline infrastructure — CI/CD-adjacent with over-provisioned cloud IAM — means successful exploitation delivers credential theft that cascades to data stores, model registries, and cloud control plane.

HIGH Vulnerability existence and exploitability
HIGH Active in-the-wild exploitation
MEDIUM Blast radius estimate (depends on cloud provider metadata protections and IAM role scope)

Why this verdict

  • Zero authentication barrier: The webhook test endpoint requires no credentials, no API key, no session — any network-reachable attacker can fire the exploit with a single POST request. This is the widest possible attack surface.
  • Active exploitation confirmed: watchTowr honeypots detected scanning and exploitation within hours of disclosure. This is not theoretical; it is happening now against production MLflow deployments.
  • Role multiplier: MLflow tracking servers are CI/CD-adjacent ML infrastructure. They canonically run on cloud VMs/containers with IAM roles granting access to S3/GCS training data, model artifact stores, Secrets Manager, and container registries. ≥50% of MLflow deployments occupy this high-value role by definition. A successful credential theft cascades from host-level to cloud-account-level, enabling data exfiltration and potential supply-chain compromise via model artifact tampering. The blast radius is cloud-account-scale, setting a CRITICAL floor.
  • Massive and growing attack surface: Shodan data shows MLflow internet exposure up 173% YoY with thousands of instances publicly reachable, many running default configs with no authentication layer.
  • Trivial exploit complexity: The attack requires only a public HTTP redirect server and a single curl command. No memory corruption, no race condition, no chain of bugs — just one request.

Why not higher?

The score is already at 9.3 CRITICAL, which is appropriate. A 10.0 would require arbitrary code execution with no mitigating factors. This is a read-only SSRF (C:H/I:L/A:N), not RCE, and cloud metadata protections (IMDSv2, GKE Workload Identity) do provide a meaningful partial mitigation on hardened deployments.

Why not lower?

Downgrading would require ignoring three compounding factors: (1) active exploitation in the wild, (2) zero authentication requirements on a network-exposed service, and (3) the CI/CD-adjacent role multiplier where credential theft cascades to cloud-account-level compromise. The IMDSv2 friction point only applies to AWS deployments that have enforced it — many have not, and GCP/Azure metadata protections vary. The growing internet exposure surface eliminates any 'niche deployment' argument.

05 · Compensating Control

What to do — in priority order.

  1. Enforce IMDSv2 on all AWS instances running MLflow — IMDSv2 requires a PUT request with a hop-limit-1 token before credential retrieval. MLflow's redirect-based SSRF cannot satisfy this, completely blocking the credential-theft path on AWS. Deploy within 3 days per noisgate mitigation SLA for CRITICAL findings. Use aws ec2 modify-instance-metadata-options --instance-id <id> --http-tokens required --http-put-response-hop-limit 1.
  2. Place MLflow behind an authenticating reverse proxy or VPN — MLflow has no built-in authentication. Deploy an OAuth2 proxy, Cloudflare Access, or restrict access to VPN/Zero-Trust overlay within 3 days. This eliminates the unauthenticated attack vector entirely.
  3. Deploy network-level metadata firewall — On GKE, enable Workload Identity. On EKS, use IRSA instead of instance profiles. On bare VMs, use iptables to block the MLflow process from reaching 169.254.169.254. Deploy within 3 days.
  4. Apply WAF rules blocking SSRF payloads — Configure WAF to inspect POST body parameters for 169.254.169.254, 127.0.0.1, and RFC-1918 ranges in webhook URL fields. This provides defense-in-depth but is bypassable via DNS rebinding.
  5. Upgrade to MLflow 3.15.0 — The definitive fix. The patched version re-validates redirect destinations against the same IP blocklist. Plan upgrade within the 90-day noisgate remediation SLA, but given active exploitation, prioritize immediate deployment.
What doesn't work
  • Network segmentation alone — MLflow needs outbound HTTP to deliver webhooks by design; blocking all outbound from MLflow breaks functionality. The SSRF exploits *intended* outbound connectivity.
  • Application-layer rate limiting — The exploit succeeds on a single request; rate limiting does not prevent exploitation, only slows scanning.
  • Disabling webhooks via config — MLflow does not have a clean feature flag to disable the webhook test endpoint without code modification; the /test route is always registered.
06 · Verification

Crowdsourced verification payload.

Run this script on each host running MLflow (or from an auditor workstation with pip access to the MLflow environment). No special privileges required. Invoke: bash check_cve_2026_64849.sh or bash check_cve_2026_64849.sh /path/to/python

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# CVE-2026-64849 checker — MLflow unauthenticated SSRF in webhook delivery
# Usage: bash check_cve_2026_64849.sh [/path/to/python]
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PYTHON="${1:-python3}"

if ! command -v "$PYTHON" &>/dev/null; then
  echo "UNKNOWN — python3 not found"
  exit 2
fi

VERSION=$($PYTHON -c "import mlflow; print(mlflow.__version__)" 2>/dev/null) || {
  echo "UNKNOWN — mlflow is not installed in this Python environment"
  exit 2
}

echo "Detected MLflow version: $VERSION"

# Compare versions using Python for reliability
RESULT=$($PYTHON -c "
from packaging.version import Version
import sys
try:
    v = Version('$VERSION')
    if v >= Version('3.15.0'):
        print('PATCHED')
    else:
        print('VULNERABLE')
except Exception as e:
    print('UNKNOWN')
" 2>/dev/null) || {
  # Fallback if packaging module unavailable
  RESULT=$($PYTHON -c "
import sys
parts = '$VERSION'.split('.')
try:
    major, minor = int(parts[0]), int(parts[1])
    if (major > 3) or (major == 3 and minor >= 15):
        print('PATCHED')
    else:
        print('VULNERABLE')
except:
    print('UNKNOWN')
")
}

echo "$RESULT — CVE-2026-64849 (MLflow SSRF in webhook delivery)"
case "$RESULT" in
  PATCHED)    exit 0 ;;
  VULNERABLE) exit 1 ;;
  *)          exit 2 ;;
esac
07 · Bottom Line

If you remember one thing.

TL;DR
Patch or mitigate immediately. CVE-2026-64849 is being actively exploited in the wild as of 2026-08-18 — attackers are scanning for exposed MLflow instances and stealing cloud credentials via the unauthenticated webhook SSRF. Under the noisgate mitigation SLA for CRITICAL findings, you have 3 days to deploy compensating controls: enforce IMDSv2 on AWS, place MLflow behind an authenticating proxy, and deploy metadata firewalls on GKE/EKS. Under the noisgate remediation SLA, upgrade to MLflow 3.15.0 within 90 days, but given active exploitation, treat the upgrade as a same-week priority. Monday morning: inventory all MLflow tracking servers (check Shodan/internal asset management for port 5000), confirm none are internet-exposed without authentication, enforce IMDSv2 on every instance running MLflow, and begin staging the 3.15.0 upgrade. If you cannot upgrade immediately, the authenticating reverse proxy is your single highest-impact compensating control.

Sources

  1. CyberPress — Hackers Exploit MLflow SSRF Flaw
  2. GitLab Advisory Database — CVE-2026-64849
  3. THREATINT — CVE-2026-64849
  4. GHSA-7gwp-5pfp-969j — GitHub Security Advisory
  5. OpenA2A Research — AI Exposure Sweep April 2026
  6. CWE-918: Server-Side Request Forgery
  7. MLflow GitHub — Fix PR #24258
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.