Moderate severityNVD Advisory· Published Dec 8, 2025· Updated Dec 9, 2025
NiceGUI Reflected XSS in ui.add_css, ui.add_scss, and ui.add_sass via Style Injection
CVE-2025-66469
Description
NiceGUI is a Python-based UI framework. Versions 3.3.1 and below are vulnerable to Reflected XSS through its ui.add_css, ui.add_scss, and ui.add_sass functions. The functions lack proper sanitization or encoding for the JavaScript context they generate. An attacker can break out of the intended <style> or <script> tags by injecting closing tags (e.g., </style> or </script>), allowing for the execution of arbitrary JavaScript. This issue is fixed in version 3.4.0.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
niceguiPyPI | < 3.4.0 | 3.4.0 |
Affected products
1- Range: < 3.4.0
Patches
13 files changed · +30 −4
nicegui/functions/style.py+4 −4 modified@@ -17,7 +17,8 @@ def add_css(content: Union[str, Path], *, shared: bool = False) -> None: """ if helpers.is_file(content): content = Path(content).read_text(encoding='utf-8') - add_head_html(f'<style>{content}</style>', shared=shared) + safe_content = json.dumps(content).replace('<', r'\u003c') + add_head_html(f'<script>addStyle({safe_content});</script>', shared=shared) def add_scss(content: Union[str, Path], *, indented: bool = False, shared: bool = False) -> None: # DEPRECATED @@ -35,12 +36,11 @@ def add_scss(content: Union[str, Path], *, indented: bool = False, shared: bool """ content = Path(content).read_text(encoding='utf-8') if helpers.is_file(content) else str(content).strip() syntax = 'indented' if indented else 'scss' + safe_content = json.dumps(content).replace('<', r'\u003c') add_head_html(f''' <script type="module"> import * as sass from "sass"; - const style = document.createElement("style"); - style.textContent = sass.compileString({json.dumps(content)}, {{syntax: "{syntax}"}}).css; - document.head.appendChild(style); + addStyle(sass.compileString({safe_content}, {{syntax: "{syntax}"}}).css); </script> ''', shared=shared)
nicegui/templates/index.html+3 −0 modified@@ -34,6 +34,9 @@ <script type="importmap"> {"imports": {{ imports | safe }}} </script> + <script> + addStyle = (c) => document.head.append(Object.assign(document.createElement("style"), { textContent: c })); + </script> {{ head_html | safe }} <!-- prevent Prettier from removing this line --> {% for url in js_imports_urls %}
tests/test_add_html.py+23 −0 modified@@ -63,3 +63,26 @@ def page(): screen.open('/') assert screen.find('This is purple on yellow with SASS.').value_of_css_property('color') == 'rgba(128, 0, 128, 1)' + + +def test_add_css_with_script(screen: Screen): + @ui.page('/') + def page(): + ui.add_css("</style></script><script>document.write('XSS');</script>") + ui.label('Hello, World!') + + screen.open('/') + screen.should_contain('Hello, World!') + screen.should_not_contain('XSS') + + +def test_add_scss_with_script(screen: Screen): + @ui.page('/') + def page(): + ui.add_scss("</style></script><script>document.write('XSS');</script>") + ui.label('Hello, World!') + + screen.allowed_js_errors.append('static/sass.dart.js') + screen.open('/') + screen.should_contain('Hello, World!') + screen.should_not_contain('XSS')
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-72qc-wxch-74mgghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-66469ghsaADVISORY
- github.com/zauberzeug/nicegui/commit/a8fd25b7d5e23afb1952d0f60a1940e18b5f1ca8ghsax_refsource_MISCWEB
- github.com/zauberzeug/nicegui/security/advisories/GHSA-72qc-wxch-74mgghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.