SA-26-165 Medium

Jupyter: JupyterLab: Stored XSS in extension manager through package metadata unsanitized URI protocol

Jupyter

Severity
Medium, CVSS 5.1
CVSS vector
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Record
GHSA-vmhf-c436-hxj4
Affects
Jupyter
Known exploited
Not listed in the CISA Known Exploited Vulnerabilities catalog
Published
Record first published by the source
June 19, 2026
Source last modified
June 19, 2026

Description

A malicious PyPI package can place a javascript: URL in its [project.urls] metadata. JupyterLab's Extension Manager renders this as the extension's home-page link without validating the protocol, so a user who clicks the extension name executes attacker-controlled JavaScript in the JupyterLab origin.

Details

One of the PyPI package's URL (jupyterlab/extensions/pypi.py) is copied straight into the homepage_url rendered by the frontend in packages/extensionmanager/src/widget.tsx#L77-L88.

best_guess_home_url = (
    homepage_url            # home_page / [project.urls] Homepage
    or data.get("project_url")
    or data.get("package_url")
    or documentation_url    # docs_url / [project.urls] Documentation
    or source_url           # [project.urls] Source Code
    or bug_tracker_url      # bugtrack_url / [project.urls] Bug Tracker
)

# homepage_url=best_guess_home_url
{entry.homepage_url ? (
  <a href={entry.homepage_url} target="_blank" rel="noopener noreferrer" ...>
    {entry.name}
  </a>
) : ( <div>{entry.name}</div> )}

Impact

An attacker needs to publish a package to PyPI (no access to the target). When the package appears in a victim's extension manager list and the victim clicks the extension name, the payload runs in the JupyterLab origin.

Preconditions: Extension Manager enabled with the default PyPI source, the malicious package appears in the victim's list/search results.

Patches

Patched in [4.5.9](https://github.com/jupyterlab/jupyterlab/releases/tag/v4.5.9), commits [4e61e07](https://github.com/jupyterlab/jupyterlab/commit/4e61e07d0a91145b53fbf96ac74b0387f6bc51f6) and [d5d961f](https://github.com/jupyterlab/jupyterlab/commit/d5d961f6e10a6442dddbf94d9a976b3897055a12)

Description quoted from the GitHub Advisory Database.

Sources

MORE ADVISORIES

See all