CVE-2026-25516
MEDIUM6.1EPSS 0.02%NiceGUI's XSS vulnerability in ui.markdown() allows arbitrary JavaScript execution through unsanitized HTML content
描述
## 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! <img src=x onerror="alert(\'XSS\')">' 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.
受影響套件(1)
- PyPI/niceguifrom 0, < 3.7.0
CVSS 分數
| 來源 | 版本 | 嚴重程度 | 向量 |
|---|---|---|---|
| osv | CVSS 3.1 | MEDIUM6.1 | CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N |