flawopen.com/AI Security/mlflow-webhook-ssrf-cve-2026-64849
CVE-2026-64849: SSRF Webhook MLflow
CVE-2026-64849 adalah server-side request forgery (SSRF) tanpa autentikasi pada pengiriman webhook MLflow (tinggi, CVSS 3.1: 8.6). Pemeriksaan URL awal tidak membatasi tujuan redirect atau alamat koneksi sebenarnya; endpoint pengujian dapat mengembalikan isi respons upstream kepada pemanggil.[1]
Bayangkan petugas penerima memeriksa alamat pada paket, tetapi membiarkan kurir mengikuti catatan pengalihan tanpa memeriksa alamat baru. MLflow memeriksa URL webhook sebelum terhubung, tetapi redirect dan pencarian DNS kedua dapat mengirim permintaan ke tempat lain. Perbaikan memeriksa alamat peer yang benar-benar terhubung sebelum mengirim data HTTP.[1], [2]
Konsep Kunci & Istilah
SSRF- Server melakukan permintaan jaringan yang dipilih pemanggil sehingga melintasi batas kepercayaan jaringan server.[1]
Endpoint uji webhook- API MLflow yang mengirim peristiwa uji ke webhook terkonfigurasi; server default terdampak mengembalikan isi respons upstream.[1]
Pemetaan kerangka kerja
- Referensi CWE untuk kelemahan yang dijelaskan dalam panduan ini: CWE-918
- D3-OTF Penyaringan Lalu Lintas Keluar — Pembatasan jaringan keluar dalam panduan ini membatasi tujuan yang dapat dijangkau layanan atau host.
- CISA KEV — ditambahkan 2026-08-19 — CVE-2026-64849
Alur Serangan Langkah demi Langkah
Server MLflow yang dapat dijangkau menerima uji webhook
Advisory menjelaskan Tracking Server default tanpa autentikasi. Plugin autentikasi dan kontrol deployment dapat mengubah keterjangkauan; periksa konfigurasi aktual. CISA menambahkan CVE ini ke katalog Known Exploited Vulnerabilities pada 19 Agustus 2026; pencantuman menunjukkan eksploitasi yang diketahui, tetapi tidak membuktikan kompromi pada deployment tertentu.[1], [4], [5]
URL awal lolos validasi
_validate_webhook_url menyelesaikan dan memeriksa hostname awal, tetapi alamat yang diperiksa dibuang dan tidak diikat ke socket berikutnya.[1]
Redirect atau resolusi ulang mencapai tujuan lain
Klien HTTP mengikuti redirect dan koneksi dapat menyelesaikan hostname lagi. Endpoint uji memantulkan isi respons upstream sehingga SSRF dapat membaca respons penuh.[1]
Perbaikan upstream memeriksa peer yang terhubung
PR #24258 memvalidasi peer socket tepat setelah koneksi dan sebelum data TLS/HTTP; sesi juga menghindari proxy lingkungan. MLflow 3.15.0 memperbaiki CVE ini; bypass transisi IPv6 yang terpisah diperbaiki pada 3.16.0. Advisory tersebut mencantumkan freeman-bb sebagai pelapor privat pertama dan AUTHENSOR sebagai penemu independen.[1], [2], [3], [6]
Kode Sumber: Rentan vs Aman
Cuplikan menunjukkan batas antara validasi URL dan permintaan aktual serta pemeriksaan peer saat koneksi. Permintaan eksploit dan tujuan internal dihilangkan. Normalisasi IPv6 di 3.16.0 adalah hardening lanjutan yang terpisah.[2]
# PR #24258 sebelum diterapkan, dari mlflow/webhooks/delivery.py.
_validate_webhook_url(webhook.url) # checks the initial URL only
return session.post(
webhook.url, data=payload_bytes, headers=headers, timeout=timeout
) # redirects follow by default; the validated IP is not pinned
# Cuplikan perbaikan upstream yang memeriksa peer saat koneksi dibuat.
def _assert_public_peer(sock):
if _MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPS.get():
return
try:
peer_ip = sock.getpeername()[0]
except OSError as exc:
sock.close()
raise SSRFProtectionError(
f"Could not determine webhook connection peer address: {exc}"
) from exc
try:
ip = ipaddress.ip_address(peer_ip)
except ValueError as exc:
sock.close()
raise SSRFProtectionError(
f"Webhook connection resolved to an invalid IP address: {peer_ip!r}"
) from exc
if not ip.is_global:
sock.close()
raise SSRFProtectionError(
f"Webhook connection blocked: {ip} is not a public IP address. "
"This may indicate a DNS rebinding attempt."
)
class _SSRFProtectedHTTPConnection(HTTPConnection):
def _new_conn(self):
sock = super()._new_conn()
_assert_public_peer(sock)
return sock
class _SSRFProtectedHTTPSConnection(HTTPSConnection):
def _new_conn(self):
sock = super()._new_conn()
_assert_public_peer(sock)
return sock
adapter = SSRFProtectedHTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.trust_env = False
session.mount("http://", adapter)
session.mount("https://", adapter)
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Untuk
CVE-2026-64849, tingkatkan MLflow 3.10.0–3.14.x ke setidaknya 3.15.0; utamakan rilis terbaru yang didukung. Deploy 3.16.0 atau lebih baru bila mekanisme transisi IPv6 dapat digunakan.[1], [3], [6] - ✓Pastikan Tracking Server tidak dapat dijangkau dari jaringan tidak tepercaya; periksa apakah plugin autentikasi opsional dan pemeriksaan otorisasi aktif. Pembatasan jaringan adalah defense-in-depth, bukan pengganti upgrade.[1]
- ✓Batasi egress server ke tujuan yang diperlukan dan blokir loopback, link-local, jaringan privat, serta metadata cloud pada lapisan jaringan. Validasi ulang setiap redirect dan peer yang terhubung di kode permintaan keluar. Biarkan
MLFLOW_WEBHOOK_ALLOW_PRIVATE_IPSnonaktif di produksi; aktifkan hanya bila benar-benar perlu di lingkungan pengembangan terisolasi.[2], [7] - ✓Tambahkan uji regresi CI untuk memastikan alamat nonpublik langsung, tujuan redirect, DNS rebinding, pool HTTP/HTTPS, dan rute proxy ditolak sebelum data permintaan dikirim; uji pengecualian IP privat secara terpisah.[2], [7]