GitHub Advisoryadvisory · PyPI
GHSA-v82v-c5x8-w282 NiceGUI's XSS vulnerability in ui.markdown() allows arbitrary JavaScript execution through unsanitized HTML content
MEDIUM
Official page ↗
- Aliases
- CVE-2026-25516
- Ecosystem
- PyPI
- Packages
- nicegui
- Severity
- Moderate
- CVSS vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Weaknesses
- CWE-79
- Reviewed
- 2026-02-05
Affected packages
• PyPI nicegui: < 3.7.0 → fixed in 3.7.0
Description
Description
The `ui.markdown()` component uses the `markdown2` library to convert markdown content to HTML, which is then rendered via `innerHTML`. By default, `markdown2` allows raw HTML to pass through unchanged. This means that if an application renders user-controlled content through `ui.markdown()`, an attacker can inject malicious HTML containing JavaScript event handlers.
Unlike other NiceGUI components that render HTML (`ui.html()`, `ui.chat_message()`, `ui.interactive_image()`), the `ui.markdown()` component does not provide or require a `sanitize` parameter, leaving applications vulnerable to XSS attacks.
Proof of Concept
```python
from nicegui import ui
User-controlled input containing malicious payload
user_input = 'Hello! '
ui.markdown(user_input) # XSS executes when page loads
ui.run()
```
When this page loads, the JavaScript in the `onerror` handler executes, potentially allowing an attacker to:
• Steal session cookies or authentication tokens
• Perform actions on behalf of the user
• Redirect users to malicious sites
• Modify page content
Impact
Applications that render user-provided content through `ui.markdown()` are vulnerable to stored or reflected XSS attacks. This is particularly concerning for:
• Chat applications displaying user messages
• CMS or documentation systems with user-editable content
• Any application that displays markdown from untrusted sources
Remediation
A release has been published in version 3.7.0.
For Users (Immediate Workaround)
Until a fix is released, do not pass untrusted content directly to `ui.markdown()`. Instead, use one of these approaches:
Option 1: Convert and sanitize manually using `ui.html()`
```python
import markdown2
from html_sanitizer import Sanitizer
sanitizer = Sanitizer()
def safe_markdown(content: str) -> None:
"""Render markdown with HTML sanitization."""
html = markdown2.markdown(content)
ui.html(sanitizer.sanitize(html), sanitize=False)
Usage
safe_markdown(user_input)
```
Option 2: Escape HTML before markdown conversion (if raw HTML not needed)
```python
import html
Escape HTML entities - prevents any HTML from being interpreted
ui.markdown(html.escape(user_input))
```
Proposed Fix
Add a `sanitize` parameter to `ui.markdown()` consistent with other HTML-rendering components, and/or add an `escape_html` parameter.
Related
Alias · CVE (1)
- CVE-2026-25516 NiceGUI is a Python-based UI framework. vulnerability
Weakness · CWE (1)
- CWE-79 Improper Neutralization of Input During Web Page Generation weakness