Skip to content

JupyterLab Desktop: one-click server token leak in untrusted notebook leading to remote code execution

Critical
krassowski published GHSA-2mr8-962v-wc67 Jul 24, 2026

Package

jupyterlab-desktop

Affected versions

<=v4.2.5-1

Patched versions

4.6.2-1

Description

Summary

On all platforms, JupyterLab Desktop versions prior to v4.6.2-1 exposed a getServerInfo IPC method to the renderer process that returned the full local Jupyter server URL - including the authentication token and port - regardless of whether the renderer had navigated away from the original JupyterLab page.

Combined with a missing target=_blank and noopener enforcement on links rendered by the MathJax HTML extension, an attacker could embed a crafted link in an untrusted notebook. A single click on that link navigates the JupyterLab Desktop window to an attacker-controlled site, which can then call getServerInfo to obtain the token. With the token, the attacker can use the Jupyter REST API to create a trusted notebook and execute arbitrary code on the victim's machine.

User interaction required: the victim must open a malicious notebook and click one link within it.

This issue affects all platforms (macOS, Windows, Linux). Users who had independently upgraded the JupyterLab version within their environment to ≥ 4.4.8 (which patches GHSA-vvfj-2jqx-52jm) are not affected, as the MathJax link enforcement in that release prevents Step 1 of the attack chain.

Note: CVE assignment pending - GitHub is experiencing a severe backlog in CVE assignment at the moment, please check back later if you need a CVE for this vulnerability.

Impact

An attacker who can deliver a malicious notebook to a victim - for example by sharing it as a file, via email, or through a code-sharing platform - can achieve remote code execution on the victim's machine if the victim opens the notebook and clicks one link within it.

Users are affected if all of the following conditions are true:

  • they are running JupyterLab Desktop up to and including v4.2.5-1;
  • the JupyterLab version in their environment is earlier than 4.4.8;
  • they open the notebook in a local session (i.e. JupyterLab Desktop manages its own local Jupyter server, which is the default behaviour); and
  • they click a link within the notebook.

By default, a link using the vulnerable component would render in a font different from normal links, however an attacker could include styles aimed at disguising the link in the notebook outputs.

Attack chain

The vulnerability is a combination of two weaknesses that are individually lower-severity but together enable one-click RCE:

  • Step 1: Link escapes sandbox via MathJax HTML extension. Jupyter's notebook security model sanitizes HTML in untrusted notebooks and enforces target=_blank and noopener on links, so that clicking a link opens an external site in a new window that has no access to the JupyterLab renderer context. However, links rendered by the MathJax HTML extension in the old JupyterLab versions (<4.4.8) bypassed this enforcement: the link lacked target=_blank and noopener, so clicking it navigated the existing JupyterLab Desktop window to the attacker's site rather than opening a new one.
  • Step 2: Attacker's site calls getServerInfo. After navigation, the attacker's page runs in the same Electron renderer window that previously held JupyterLab. The getServerInfo IPC method, exposed via the electronAPI preload bridge, remained accessible and returned the original local Jupyter server URL, including the randomised port and authentication token.
  • Step 3: Token used to achieve RCE. With the token, the attacker calls the Jupyter REST API to create a new notebook, mark it as trusted, and navigate the victim to it. Viewing a trusted notebook is equivalent to executing code under Jupyter's security model, giving the attacker arbitrary code execution on the victim's machine.

Patches

Both weaknesses are fixed in v4.6.2-1:

  • The getServerInfo IPC method no longer returns the server URL after the renderer has navigated away from the JupyterLab origin.
  • Links rendered by LaTeX typesetters now enforce target=_blank and noopener in JupyterLab 4.4.8+

All users should upgrade to v4.6.2-1.

Workarounds

Users who cannot immediately upgrade should:

  • Upgrade JupyterLab to ≥ 4.4.8 within their environment (pip install --upgrade "jupyterlab>=4.4.8"). This patches the upstream MathJax link issue and breaks the attack chain at Step 1, even without upgrading JupyterLab Desktop itself.
  • Avoid opening notebooks from untrusted sources in JupyterLab Desktop.
  • Avoid clicking links inside notebooks whose provenance is not fully trusted.

Disabling the MathJax plugin is another workaround for users who cannot upgrade either of the versions:

jupyter labextension disable @jupyterlab/mathjax-extension

References

  • GHSA-vvfj-2jqx-52jm - upstream JupyterLab advisory for missing noopener on LaTeX typesetter links (patched in JupyterLab 4.4.8)
  • 7f8f64a

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H

CVE ID

No known CVE

Weaknesses

Exposure of Sensitive Information to an Unauthorized Actor

The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information. Learn more on MITRE.

Origin Validation Error

The product does not properly verify that the source of data or communication is valid. Learn more on MITRE.

Use of Web Link to Untrusted Target with window.opener Access

The web application produces links to untrusted external sites outside of its sphere of control, but it does not properly prevent the external site from modifying security-critical properties of the window.opener object, such as the location property. Learn more on MITRE.

Credits