CVE-2026-54064High· 8.7▾ TwilightNukeViet: Multiple Anti-XSS Filter Bypasses Leading to Stored XSS in News Module
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 47.8 · likelihood 0 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Two filter-bypass techniques in NukeViet\Core\Request::filterAttr() and NukeViet\Core\Request::unhtmlentities() allow a low-privileged user (any account with news post permission) to store and serve arbitrary JavaScript to any visitor of the affected page.
vendor/vinades/nukeviet/Core/Request.php — class NukeViet\Core\Request
\x0C) before event handler nameThe filterAttr() method blocks event-handler attributes using:
preg_match('/^on/i', $attrSubSet[0])
PHP's trim() does not strip the ASCII Form Feed character (\x0C, U+000C). An attacker can prefix the attribute name with \x0C so that \x0Conerror does not match /^on/. The HTML5 browser parser treats \x0C as a valid whitespace separator and correctly activates the event handler.
Proof-of-concept payload (URL-encoded POST body field bodyhtml):
<img src="x" %0Conerror="alert('XSS')">
	) inside javascript: URIunhtmlentities() strips the hex-encoded tab 	 via str_ireplace, but did not strip its decimal equivalent 	. The keyword-blocking regex /j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t/si uses \s* which does not match HTML entities. The value jav	ascript:alert() passes the filter, is stored in the database, and is decoded by the browser into a working javascript: URI.
Proof-of-concept payload (inside a Markdown-style link):
[Click me](jav	ascript:alert('XSS'))
An authenticated attacker with news-posting permission can inject persistent JavaScript that executes in the browser of any user (including administrators) who views the affected article. This enables session cookie theft, credential harvesting, defacement, and further privilege escalation.
Fixed in commit <commit-sha> by modifying vendor/vinades/nukeviet/Core/Request.php:
filterAttr() — strip all ASCII control characters (\x00–\x20) from the attribute name before the /^on/ check:
$attrSubSet[0] = preg_replace('/[\x00-\x20]/', '', strtolower($attrSubSet[0]));
unhtmlentities() — strip decimal HTML entities for all ASCII control characters (0–31) before the keyword checks:
$value = preg_replace('/�*(?:3[01]|[12][0-9]|[0-9]);/', '', $value);
None. Update to the patched version.
nukeviet/nukeviet < 4.6.00Upgrade to a patched release:
nukeviet/nukeviet 4.6.00Connected by shared product, vendor, weakness, or advisory.
CVE-2026-48118High· 8.2NukeViet: Unauthenticated Reflected XSS in Comment Module
CVE-2026-49259High· 8.7NukeViet: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CVE-2026-54065High· 8.7NukeViet: Path Traversal to Arbitrary File Deletion in Edit Comment Function
CVE-2026-55372High· 7.2NukeViet: Pre-authentication SSRF via X-Forwarded-Host
CVE-2021-41164High· 8.2CKEditor4 is an open source WYSIWYG HTML editor
CVE-2021-41184Medium· 6.5jQuery-UI is the official jQuery user interface library