MEDIUM 5.4

CVE-2026-44727: Jupyter Server Stored XSS via nbconvert HTML Rendering

Jupyter Server versions before 2.20 contain a stored cross-site scripting (XSS) vulnerability in the notebook conversion feature. When a user opens a malicious notebook through the web interface, specially crafted HTML content in the notebook can execute arbitrary JavaScript in the browser with access to session cookies and the Jupyter API. An attacker who can get a user to open a prepared notebook—either by hosting it or tricking them into uploading it—can steal credentials, modify notebooks, or execute code on the Jupyter kernel itself. The vulnerability requires user interaction (opening the notebook) and authenticated access to Jupyter, which limits the immediate blast radius but poses significant risk in multi-user or shared research environments.

Source data · NVD / CISA · public domain

CVSS
3.1 · 5.4 MEDIUM · CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
Weaknesses (CWE)
CWE-1021, CWE-79
Affected products
1 configuration(s)
Published / Modified
2026-06-22 / 2026-07-22

NVD description (verbatim)

Jupyter Server is the backend for Jupyter web applications. Prior to 2.20, 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. This vulnerability is fixed in 2.20.

6 reference(s) · View on NVD →

SEC.co analysis · AI-assisted, reviewed against source

Technical summary

The vulnerability stems from two compounding weaknesses: (1) nbconvert's HTTP handlers render converted notebook HTML at the Jupyter origin without a sandbox Content-Security-Policy directive, and (2) HTMLExporter does not sanitize user-supplied HTML by default. When a notebook contains a display_data output with malicious HTML/JavaScript, the conversion handler serves it unsanitized under the Jupyter domain. This allows the attacker's script to access httpOnly cookies (if not properly flagged), invoke Jupyter API endpoints with the victim's credentials, and potentially reach the kernel execution interface. The attack is stored—the payload persists in the notebook file, affecting any user who subsequently opens it.

Business impact

In collaborative environments (research teams, data science platforms, educational institutions), this creates a supply-chain-like risk: a single compromised or malicious notebook can compromise multiple users. An attacker who gains write access to shared notebook storage or convinces a user to import an external notebook can harvest session tokens, modify or delete other users' notebooks, or pivot to kernel execution for lateral movement. Organizations relying on Jupyter for sensitive analysis face data confidentiality and integrity risks. The requirement for authentication and user action limits mass-scale exploitation but does not eliminate the threat, especially where notebook sharing is common.

Affected systems

Jupyter Server prior to version 2.20 is affected. This includes deployments of JupyterHub, JupyterLab, and other Jupyter-based applications that bundle or depend on jupyter_server < 2.20. The vulnerability does not affect installations that have already upgraded to 2.20 or later. Check your deployed version with `jupyter --version` or examine the installed package metadata.

Exploitability

Exploitation requires two preconditions: (1) an authenticated user account on the Jupyter instance, and (2) user interaction—the victim must open or render the notebook containing the payload. The attack is not remotely triggerable by an unauthenticated attacker. However, within an organization where notebooks are shared, imported from external sources, or stored in accessible repositories, the bar for crafting and delivering a malicious notebook is low. No special tools or complex interaction are needed; a standard notebook file with embedded JavaScript in a display_data cell suffices. The CVSS score of 5.4 reflects these constraints, but in practice, risk is elevated in open-collaboration scenarios.

Remediation

Upgrade Jupyter Server to version 2.20 or later. This patch implements Content-Security-Policy sandbox directives on nbconvert handlers and enables HTML sanitization by default in HTMLExporter. After patching, validate the update across all deployed instances, including JupyterHub clusters and containerized environments. For environments where immediate patching is not feasible, restrict notebook import and sharing to trusted sources, and consider disabling nbconvert or the HTTP conversion endpoint if unused.

Patch guidance

Verify the available patch version in your environment's package repository (pip, conda, etc.) and the official Jupyter Server GitHub releases. Upgrade using your package manager: `pip install --upgrade jupyter-server>=2.20` or `conda update jupyter-server`. If you manage JupyterHub or a Jupyter container, ensure the base image or environment includes the patched version. Test the upgrade in a non-production environment first to confirm compatibility with any custom nbconvert templates or extensions. Restart Jupyter services after patching.

Detection guidance

Monitor for CVE-2026-44727 exploitation indicators: (1) Jupyter server access logs showing POST/GET requests to /nbconvert endpoints with unusual payloads or suspicious query parameters; (2) browser-based detection via Content Security Policy violation reports if CSP is enabled; (3) audit logs showing unexpected API calls or kernel execution following notebook access; (4) presence of <script> or event handler tags in display_data cells in notebooks. Inspect notebook files for suspicious HTML/JavaScript in output cells. Check Jupyter Server version in deployment configs or runtime environment. Use vulnerability scanning tools that fingerprint jupyter_server version.

Why prioritize this

This vulnerability merits near-term remediation despite its medium CVSS score because it enables credential theft and code execution in trusted development environments. The stored XSS nature means a single malicious notebook can compromise multiple users over time. While it requires authentication and user interaction, the low friction of notebook sharing and the sensitivity of data in research and analytics environments elevate practical risk. Organizations with shared Jupyter deployments, especially those handling sensitive data or connected to critical systems, should prioritize this patch.

Risk score, explained

CVSS 5.4 (Medium) reflects: network-accessible attack surface (AV:N), low complexity (AC:L), requirement for valid authentication (PR:L), mandatory user interaction (UI:R), and scope change allowing the attacker to affect resources beyond the vulnerable component (S:C). The score does not fully capture the impact of stored XSS in collaborative settings, where one compromised notebook reaches many users, nor the sensitivity of Jupyter environments. Organizations should consider their notebook-sharing practices and data sensitivity when contextualizing this score.

Frequently asked questions

Can an unauthenticated attacker exploit this?

No. The vulnerability requires an authenticated account on the Jupyter instance and user interaction (opening the notebook). An unauthenticated attacker cannot directly trigger it, but may socially engineer a user to import a malicious notebook from an external source.

Does this affect only JupyterLab or all Jupyter deployments?

The underlying vulnerability is in Jupyter Server, the backend component shared by JupyterLab, JupyterHub, and other Jupyter-based applications. Any deployment using jupyter_server < 2.20 is affected, regardless of the frontend or hosting model.

What can an attacker actually do if they exploit this?

A successful exploit allows the attacker to steal session cookies, make API calls as the victim user (including listing, modifying, or deleting notebooks), and potentially execute code on the Jupyter kernel—effectively gaining the computational and data access of the compromised user account.

Is there a workaround if I cannot patch immediately?

Temporary mitigations include: restricting notebook imports to trusted sources, disabling or isolating the nbconvert HTTP endpoints, educating users not to open notebooks from untrusted sources, and monitoring for suspicious notebook content and API activity. However, these are not substitutes for patching.

This analysis is based on the CVE description and publicly available information as of the stated publication date. Organizations should verify patch availability, compatibility, and version numbers against official Jupyter Server advisories and release notes. Actual risk and exploitability may vary based on deployment architecture, network controls, user behavior, and data sensitivity. This document does not constitute security advice and should be reviewed in the context of your organization's threat model and compliance requirements. No exploit code or detailed weaponization instructions are provided; defensive measures should be applied promptly. Source: NVD (public-domain), retrieved 2026-07-28. Analysis generated by SEC.co (claude-haiku-4-5).