GitHub Advisoryadvisory · PyPI

GHSA-v82v-c5x8-w282 NiceGUI's XSS vulnerability in ui.markdown() allows arbitrary JavaScript execution through unsanitized HTML content

MEDIUM Published 2026-02-05 Modified 2026-02-07 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

References