MLflow: Unauthenticated full-read SSRF in webhook delivery: _validate_webhook_url bypassed via unvalidated HTTP redirects (and DNS rebinding)
### 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_addre
GHSA-7gwp-5pfp-969j
Primary source · Revision 1
Imported from structured advisory data. Source references identify upstream records or fields; verify affected versions and your deployed configuration.
Security context
Source reference: osv:GHSA-7gwp-5pfp-969j
mlflow
Source reference: /affected/0/package/name
- Affected versions
- 3.10.0
Source reference:
/affected/0/versions3.10.0rc0Source reference:
/affected/0/versions3.10.1Source reference:
/affected/0/versions3.11.0Source reference:
/affected/0/versions3.11.0rc0Source reference:
/affected/0/versions3.11.0rc1Source reference:
/affected/0/versions3.11.1Source reference:
/affected/0/versions3.12.0Source reference:
/affected/0/versions3.12.0rc0Source reference:
/affected/0/versions3.13.0Source reference:
/affected/0/versions3.13.0rc0Source reference:
/affected/0/versions3.14.0Source reference:
/affected/0/versions3.3.0Source reference:
/affected/0/versions3.3.1Source reference:
/affected/0/versions3.3.2Source reference:
/affected/0/versions3.4.0Source reference:
/affected/0/versions3.4.0rc0Source reference:
/affected/0/versions3.5.0Source reference:
/affected/0/versions3.5.0rc0Source reference:
/affected/0/versions3.5.1Source reference:
/affected/0/versions3.6.0Source reference:
/affected/0/versions3.6.0rc0Source reference:
/affected/0/versions3.7.0Source reference:
/affected/0/versions3.7.0rc0Source reference:
/affected/0/versions3.8.0Source reference:
/affected/0/versions3.8.0rc0Source reference:
/affected/0/versions3.8.1Source reference:
/affected/0/versions3.9.0Source reference:
/affected/0/versions3.9.0rc0Source reference:
/affected/0/versions - Fixed versions
- 3.15.0
Source reference:
/affected/0/ranges - Prerequisites
- Not stated in this record
Structured affected-version data
Original package identities and version rules from this source.
[
{
"ranges": [
{
"type": "ECOSYSTEM",
"events": [
{
"introduced": "3.3.0"
},
{
"fixed": "3.15.0"
}
]
}
],
"package": {
"name": "mlflow",
"purl": "pkg:pypi/mlflow",
"ecosystem": "PyPI"
},
"versions": [
"3.10.0",
"3.10.0rc0",
"3.10.1",
"3.11.0",
"3.11.0rc0",
"3.11.0rc1",
"3.11.1",
"3.12.0",
"3.12.0rc0",
"3.13.0",
"3.13.0rc0",
"3.14.0",
"3.3.0",
"3.3.1",
"3.3.2",
"3.4.0",
"3.4.0rc0",
"3.5.0",
"3.5.0rc0",
"3.5.1",
"3.6.0",
"3.6.0rc0",
"3.7.0",
"3.7.0rc0",
"3.8.0",
"3.8.0rc0",
"3.8.1",
"3.9.0",
"3.9.0rc0"
],
"database_specific": {
"source": "https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/08/GHSA-7gwp-5pfp-969j/GHSA-7gwp-5pfp-969j.json"
}
}
]- Related CVEs
- CVE-2026-64849
Source reference:
/aliases
Publisher severity
critical
Source reference: /database_specific/severity
- Event
- #71335 · Revision 1
- Added to Heist Feed
- Publisher date