CVE-2026-111059
## Summary Mercury turns Jupyter notebooks into shared web apps/dashboards. The `mr.Markdown` widget converts its input to HTML with **python-markdown and no sanitization step**. `MarkdownWidget` is an `ipywidgets.HTML` widget, whose value is written to the page as **raw HTML (via `innerHTML`) with no sanitization**, so the result reaches the DOM verbatim. When an app passes **untrusted data** (database rows, user submissions, uploaded file contents, or an external/LLM API response) to `mr.Markdown`, HTML/JS in that data executes in the browser of **whoever views the app** — a data-driven stored/DOM-based XSS. This is a library-provided rendering sink that fails to neutralize output; it is triggered by ordinary, reasonable application code, not by an author mistake. ## Root cause `mercury/md.py` — `MarkdownWidget._to_html()` (verified at v3.2.6, lines ~57–65): ```python def _to_html(self, text: str) -> str: if md_lib is not None: body = md_lib.markdown(text) # python-markdown: passes raw HTML through else: body = f"<pre>{escape(text)}</pre>" # escape() is ONLY the md-lib-absent fallback return self._apply_inline_theme(body) # regex styling — adds style=, removes nothing ``` Two neutralization failures compound: 1. **Markdown → HTML is unsanitized.** `python-markdown` passes raw HTML through by default: `<img src=x onerror=…>`, `<svg onload=…>`, and `javascript:` links survive verbatim. There is no `bleach`/`nh3` allowlist anywhere in the package. `_apply_inline_theme()` only injects inline `style=` attributes via regex; it is not a sanitizer and removes nothing. `escape()` runs only in the md-lib-absent fallback. 2. **The rendering sink is unsanitized `innerHTML`.** `MarkdownWidget` (`mercury/md.py:21`) subclasses `ipywidgets.HTML`. The ipywidgets HTML widget renders its `value` into the DOM as raw HTML via `innerHTML`, with no sanitization (this is the widget's design). Event-handler payload
Properties
- Severity
- medium
- Summary
- Mercury: Stored / DOM Cross-Site Scripting (XSS): mr.Markdown renders untrusted content as raw, unsanitized HTML
- Nvd fetched at
- 2026-10-20T21:14:08.448323+00:00
- Epss score
- 0.00284
- Cvss severity
- MEDIUM
- Cvss score
- 6.1
- Retrieved at
- 2026-10-21T01:24:48+00:00
- Ghsa published
- 2026-10-19T17:01:20Z
- Source url
- https://github.com/advisories/GHSA-2658-85cv-9wwq
- Ghsa updated
- 2026-10-19T17:01:22Z
- Ghsa id
- GHSA-2658-85cv-9wwq
- Last source
- FIRST EPSS
- Score
- 6.1
- Cvss version
- 3.1
- Cve id
- CVE-2026-111059
- Cvss vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- First seen by Signal
- 2026-10-19T19:31:52+00:00
- Is ghsa only
- false
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N
- Published at
- 2026-10-19T17:17:02.940
Related Entities (4)
HAS_WEAKNESS (2)
AFFECTS (1)
VULNERABLE_TO (1)
Explore deeper with Ninja Signal's threat intelligence graph