Jupyter Server: Stored XSS in `NbconvertFileHandler` / `NbconvertPostHandler` via missing `sandbox` CSP
Critical5.4CVE-2026-44727 · Published Jun 18, 2026 · updated Sep 10, 2026
The nbconvert HTTP handlers in jupyter_server render user-authored notebook HTML under the Jupyter origin without a sandbox directive in their `Content-Security-Policy`. Combined with `nbconvert.HTMLExporter`'s default non-sanitizing behavior, a notebook carrying an HTML payload in a display_data output triggers stored XSS with cookie access, full /api/* authority, and kernel RCE. ### Impact An authenticated victim who navigates to `/nbconvert/html/<path>` containing attacker-authored output can have their token exfiltrated to another domain because it is executed in the Jupyter origin. ### Patches Fixed in v2.20.0, commit [6cbee8d](https://github.com/jupyter-server/jupyter_server/commit/6cbee8d65e71abac851c4492fea987ad080580bd) ### Workarounds For deployments where editing the installed jupyter_server is impractical (containerized builds, read-only images), adding this to jupyter_server_config.py has the same effect as the patch above without touching source files: ``` import jupyter_server.nbconvert.handlers as _nb def _csp(self): return super(type(self), self).content_security_policy + "; sandbox allow-scripts" _nb.NbconvertFileHandler.content_security_policy = pro...
Affected versions
| Package | Affected | Fixed in |
|---|---|---|
| jupyter-server PyPI | < 2.20.0 | 2.20.0 |
Details and references
The nbconvert HTTP handlers in jupyter_server render user-authored notebook HTML under the Jupyter origin without a sandbox directive in their `Content-Security-Policy`. Combined with `nbconvert.HTMLExporter`'s default non-sanitizing behavior, a notebook carrying an HTML payload in a display_data output triggers stored XSS with cookie access, full /api/* authority, and kernel RCE. ### Impact An authenticated victim who navigates to `/nbconvert/html/<path>` containing attacker-authored output can have their token exfiltrated to another domain because it is executed in the Jupyter origin. ### Patches Fixed in v2.20.0, commit [6cbee8d](https://github.com/jupyter-server/jupyter_server/commit/6cbee8d65e71abac851c4492fea987ad080580bd) ### Workarounds For deployments where editing the installed jupyter_server is impractical (containerized builds, read-only images), adding this to jupyter_server_config.py has the same effect as the patch above without touching source files: ``` import jupyter_server.nbconvert.handlers as _nb def _csp(self): return super(type(self), self).content_security_policy + "; sandbox allow-scripts" _nb.NbconvertFileHandler.content_security_policy = property(_csp) _nb.NbconvertPostHandler.content_security_policy = property(_csp) ```
- CVSS 3.1
- CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
- Severity from
- GitHub (reviewed advisory)
- Weakness
- CWE-1021, CWE-79
- Also known as
- CVE-2026-44727, PYSEC-2026-366
- github.com/jupyter-server/jupyter_server/security/advisories/GHSA-fcw5-x6j4-ccmp
- nvd.nist.gov/vuln/detail/CVE-2026-44727
- github.com/jupyter-server/jupyter_server/commit/6cbee8d65e71abac851c4492fea987ad080580bd
- access.redhat.com/errata/RHSA-2026:43038
- access.redhat.com/errata/RHSA-2026:60520
- access.redhat.com/security/cve/CVE-2026-44727
- bugzilla.redhat.com/show_bug.cgi?id=2491516
- github.com/advisories/GHSA-fcw5-x6j4-ccmp
- github.com/jupyter-server/jupyter_server
- github.com/pypa/advisory-database/tree/main/vulns/jupyter-server/PYSEC-2026-366.yaml
- pypi.org/project/jupyter-server
- security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-44727.json
More Jupyter advisories
All Jupyter| Date | Advisory | Severity | Fixed in |
|---|---|---|---|
| Jul 22 | JupyterLab: Image viewer allows XSS when opening malicious image in new browser tab | High | 4.5.10+1 more |
| Jul 22 | JupyterLab: PyPI extension blocklist package-name canonicalization bypass | Medium | 4.5.10+1 more |
| Jul 22 | JupyterLab PluginManager lock-rule enforcement bypass | Medium | 4.5.10+1 more |
| Jul 22 | Jupyter: improper access control | Low0.0 | 4.5.10+1 more |
| Jul 13 | Jupyter Server vulnerable to Path Traversal via incorrect root directory boundary check in _get_os_path() | Medium6.8 | 2.18.2 |
| Jun 19 | JupyterLab: Stored XSS in extension manager through package metadata unsanitized URI protocol | Medium | 4.5.9 |