flawopen.com/AI Security/wazuh-mcp-server-webshell-check-ssrf-ghsa-pw2j-pj4h-f5vg
Celah SSRF pada pemeriksa webshell Wazuh MCP — GHSA-pw2j-pj4h-f5vg
Nama host melewati pemeriksaan IP literal Wazuh-MCP-Server sebelum diakses oleh alat forensik. GHSA memberi tingkat keparahan High dan CWE-918; CVE belum ditetapkan. Diperbaiki pada commit 2bbfe12.[1], [2], [3]
Petugas resepsionis memeriksa apakah kartu pengunjung ada dalam daftar blokir, lalu membiarkan pengunjung memilih kantor. Memeriksa nomor yang tercetak saja tidak menunjukkan bahwa nama itu mengarah ke ruangan terlarang. Perbaikannya memeriksa hasil resolusi nama dan mengikat koneksi ke alamat yang sudah diperiksa.[1], [3]
Konsep Kunci & Istilah
Server-side request forgery (SSRF)- Server mengirim permintaan jaringan ke tujuan yang dipengaruhi pemanggilnya. Pemeriksaan tujuan yang tidak lengkap dapat membuat server menjangkau jaringan yang tidak dapat diakses pemanggil secara langsung.[4], [1]
Resolusi DNS dan rebinding- Nama host diterjemahkan menjadi satu atau beberapa alamat IP. Jika hanya teks nama yang diperiksa atau klien HTTP melakukan resolusi ulang, koneksi dapat menuju alamat berbeda dari yang telah diperiksa.[1], [3]
Penguncian alamat tujuan- IP yang sudah divalidasi diikat ke koneksi keluar, sementara nama host tetap digunakan untuk pemeriksaan HTTP dan TLS. Ini menutup jeda antara validasi dan koneksi.[3]
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.
Alur Serangan Langkah demi Langkah
URL dari data forensik masuk ke alat pemeriksa
Alat terdampak blueteam_check_webshell menerima URL agar analis dapat memeriksa alamat yang dicurigai menghosting webshell. Advisory membatasi masalah pada alat ini, bukan seluruh kemampuan Wazuh-MCP-Server.[1]
Klien HTTP melakukan resolusi dan mengikuti pengalihan
URL yang lolos pemeriksaan kemudian diberikan kepada curl, yang melakukan resolusi DNS sendiri. Advisory juga menjelaskan pengalihan otomatis tanpa validasi ulang tujuan. SSRF dapat terjadi jika server menjangkau alamat internal dan masukan yang tidak tepercaya dapat memengaruhi argumen URL. Dampak nyata bergantung pada jangkauan jaringan dan akses alat.[1], [3]
Patch memvalidasi dan mengunci alamat hasil resolusi
Commit 2bbfe12 menyelesaikan catatan IPv4 dan IPv6, menolak alamat nonpublik kecuali host secara eksplisit dikonfigurasi di ALLOWED_INTERNAL_DOMAINS, lalu mengunci alamat terpilih pada permintaan. Jalur pengambilan yang diperbaiki tidak mengikuti pengalihan otomatis. GHSA memberi tingkat High dan CWE-918; tidak ada CVE atau rentang versi paket.[1], [3]
Kode Sumber: Rentan vs Aman
Cuplikan rentan mereproduksi logika terkait WebshellCheckInput.validate_url dari commit 6bd1fa8; import dan field kelas dihilangkan. IP literal non-publik ditolak, tetapi ValueError dari nama host dianggap sebagai domain dan diterima tanpa resolusi DNS. Cuplikan yang diperbaiki mereproduksi _pinned_curl_args dari commit 2bbfe12. Validator baru juga memanggil _host_pins; loop permintaan meneruskan argumen --resolve ke curl dan memvalidasi setiap tujuan pengalihan sebelum hop berikutnya. Tujuan internal hanya diizinkan untuk domain yang dikonfigurasi secara eksplisit. Ini cuplikan kode yang terfokus, bukan pengganti seluruh alur pengambilan URL.[2], [3]
Cuplikan sumber: mcp_server/tools/webshell_check.py — validasi 6bd1fa8; perbaikan 2bbfe12
@field_validator("url")
@classmethod
def validate_url(cls, v: str) -> str:
v = v.strip()
if not v.startswith(("http://", "https://")):
raise ValueError(f"URL must start with http:// or https://, got: {v!r}")
# Tolak IP privat/tercadang pada host URL.
from urllib.parse import urlparse
import ipaddress
host = urlparse(v).hostname
if host:
try:
ip = ipaddress.ip_address(host)
except ValueError:
ip = None # not an IP - domain name, allowed
if ip is not None and (ip.is_private or ip.is_loopback or ip.is_reserved or ip.is_link_local):
raise ValueError(f"URL host is a private/reserved IP: {host}. This tool only accepts public hosts.")
return v
def _pinned_curl_args(url: str) -> tuple[list[str], str | None]:
"""Build curl --resolve args for an already-validated destination."""
import ipaddress
u = urlparse(url)
host = u.hostname
if not host:
return [], "URL has no host."
try:
ipaddress.ip_address(host)
return [], None # Literal IP: no DNS lookup to rebind.
except ValueError:
pass
port = u.port or (443 if u.scheme == "https" else 80)
ips, err = _host_pins(host, _allowed_internal_domains())
if err:
return [], err
args: list[str] = []
for ip in ips:
addr = f"[{ip}]" if ":" in ip else ip
args += ["--resolve", f"{host}:{port}:{addr}"]
return args, None
Daftar Periksa Penguatan Sistem Rekayasa
- ✓Temukan deployment yang memuat implementasi
blueteam_check_webshellterdampak; advisory menyebut commit, bukan rentang versi paket.[1], [2] - ✓Perbarui ke commit
2bbfe12atau versi lebih baru yang mencakup perbaikan dan verifikasi sumber yang benar-benar dipasang.[3] - ✓Selesaikan semua catatan A dan AAAA lalu tolak alamat nonpublik, kecuali diperlukan pengecualian domain internal yang sangat terbatas.[3]
- ✓Ikat IP yang telah divalidasi ke koneksi aktual agar resolusi DNS berikutnya tidak mengubah tujuan.[3]
- ✓Nonaktifkan pengalihan otomatis atau validasi dan kunci setiap tujuan pengalihan.[1], [3]
- ✓Batasi akses alat dan jaringan keluar server; periksa apakah data tidak tepercaya dapat mengendalikan argumen URL.[1]
- ✓Uji jawaban DNS campuran, IPv4, IPv6, pengecualian internal, pengalihan, dan penguncian tanpa menghubungi layanan internal sungguhan.[3]
Sumber
- Advisory keamanan Wazuh-MCP-Server GHSA-pw2j-pj4h-f5vg (tanpa CVE)
- Kode rentan pada commit 6bd1fa8 — WebshellCheckInput.validate_url
- Commit perbaikan Wazuh-MCP-Server 2bbfe12
- MITRE CWE-918: Server-Side Request Forgery
- The Next Web: temuan SSRF terpisah pada implementasi MCP
- Ars Technica: Vulnerability in agents from Google and others exposes structural flaw in MCP