{"id":"CVE-2026-25516","aliases":["GHSA-v82v-c5x8-w282","PYSEC-2026-2231"],"url":"https://o3.security/vulnerability/CVE-2026-25516","summary":"NiceGUI's XSS vulnerability in ui.markdown() allows arbitrary JavaScript execution through unsanitized HTML content","details":"## Description\n\nThe `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.\n\nUnlike 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.\n\n## Proof of Concept\n\n```python\nfrom nicegui import ui\n\n# User-controlled input containing malicious payload\nuser_input = 'Hello! <img src=x onerror=\"alert(\\'XSS\\')\">'\n\nui.markdown(user_input)  # XSS executes when page loads\n\nui.run()\n```\n\nWhen this page loads, the JavaScript in the `onerror` handler executes, potentially allowing an attacker to:\n- Steal session cookies or authentication tokens\n- Perform actions on behalf of the user\n- Redirect users to malicious sites\n- Modify page content\n\n## Impact\n\nApplications that render user-provided content through `ui.markdown()` are vulnerable to stored or reflected XSS attacks. This is particularly concerning for:\n- Chat applications displaying user messages\n- CMS or documentation systems with user-editable content\n- Any application that displays markdown from untrusted sources\n\n## Remediation\n\nA release has been published in version 3.7.0.\n\n### For Users (Immediate Workaround)\n\nUntil a fix is released, **do not pass untrusted content directly to `ui.markdown()`**. Instead, use one of these approaches:\n\n**Option 1: Convert and sanitize manually using `ui.html()`**\n\n```python\nimport markdown2\nfrom html_sanitizer import Sanitizer\n\nsanitizer = Sanitizer()\n\ndef safe_markdown(content: str) -> None:\n    \"\"\"Render markdown with HTML sanitization.\"\"\"\n    html = markdown2.markdown(content)\n    ui.html(sanitizer.sanitize(html), sanitize=False)\n\n# Usage\nsafe_markdown(user_input)\n```\n\n**Option 2: Escape HTML before markdown conversion (if raw HTML not needed)**\n\n```python\nimport html\n\n# Escape HTML entities - prevents any HTML from being interpreted\nui.markdown(html.escape(user_input))\n```\n\n### Proposed Fix\n\nAdd a `sanitize` parameter to `ui.markdown()` consistent with other HTML-rendering components, and/or add an `escape_html` parameter.","published":"2026-02-06T21:12:19.501Z","modified":"2026-10-28T02:30:49.152091199Z","cvss":{"score":6.1,"severity":"MEDIUM","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N"},"epss":null,"cisaKev":null,"exploitsKnown":0,"affectedPackages":[{"ecosystem":"PyPI","name":"nicegui","fixedVersion":"3.7.0"}],"fix":{"url":"https://github.com/zauberzeug/nicegui/commit/f1f7533577875af7d23f161ed3627f73584cb561","label":"zauberzeug/nicegui@f1f7533"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/25xxx/CVE-2026-25516.json"},{"type":"ADVISORY","url":"https://github.com/zauberzeug/nicegui/security/advisories/GHSA-v82v-c5x8-w282"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-25516"},{"type":"FIX","url":"https://github.com/zauberzeug/nicegui/commit/f1f7533577875af7d23f161ed3627f73584cb561"},{"type":"PACKAGE","url":"https://github.com/zauberzeug/nicegui"}],"provenance":{"sources":["OSV.dev","FIRST.org (EPSS)"],"lastVerified":"2026-10-28T02:30:49.152091199Z"}}