Skip to content

JupyterLab: Allowlist/blocklist check in `PyPIExtensionManager.install()` not enforced for direct callers (missing `await`)

Low severity GitHub Reviewed Published Jul 21, 2026 in jupyterlab/jupyterlab • Updated Jul 22, 2026

Package

pip jupyterlab (pip)

Affected versions

>= 4.6.0, <= 4.6.1
<= 4.5.9

Patched versions

4.6.2
4.5.10

Description

The extension allowlist/blocklist check inside PyPIExtensionManager.install() was not enforced due to a missing await. For purposes of JupyterLab this was a secondary defense-in-depth check: install() was intended to enforce the allowlist/blocklist itself for any future uses and users calling this method directly (in addition to the separate check handling requests arriving through the HTTP API). The only runtime symptom was a RuntimeWarning: coroutine 'is_install_allowed' was never awaited.

This has security implications only for deployments that combine all of the following:

  • a custom extension or downstream integration that imports PyPIExtensionManager and calls install() directly with a package name influenced by untrusted user input (the stock JupyterLab HTTP handler is not affected - it performs its own awaited allowlist check before calling install());
  • an allowlist/blocklist configured with the intent of restricting which packages users can install;
  • the (default) PyPI Extension Manager enabled; and
  • kernels and terminals disabled or delegated to remote hosts, so that the custom extension's install() call is the only available package-install vector (otherwise a user with kernel access can install packages directly regardless of this check)

Impact

Low. No exposure for stock JupyterLab: the HTTP API and Extension Manager UI enforce the listing through a separate, correctly awaited check. The gap affected only custom extensions or downstream integrations that called the public install() method directly and relied on it to self-enforce.

Patches

JupyterLab v4.6.2 and v4.5.10 contain the patch.

Users of applications that depend on JupyterLab, such as Notebook v7+, should update jupyterlab package too.

Workarounds

No action is required for deployments that only expose extension management through the JupyterLab HTTP API / Extension Manager UI, as that path was already enforcing the listing via the handler's own check. Deployments wanting to disable programmatic extension installation entirely can switch to the read-only extension manager:

--LabApp.extension_manager=readonly

or the following traitlet:

c.LabApp.extension_manager = 'readonly'

You can confirm that the read-only manager is in use from GUI:

image

### References - https://github.com/jupyterlab/jupyterlab/security/advisories/GHSA-whvh-wf3x-g77j - https://github.com/jupyterlab/jupyterlab/pull/19184 - https://github.com/jupyterlab/jupyterlab/pull/19185 - https://github.com/jupyterlab/jupyterlab/pull/19186 - https://github.com/jupyterlab/jupyterlab/commit/be9303f5bcd5308eaeae953c5a3c903046682c2c - https://github.com/jupyterlab/jupyterlab/commit/f1beab4a2027af4719d6edc07d52d6cf5a39a432 - https://github.com/jupyterlab/jupyterlab/releases/tag/v4.5.10 - https://github.com/jupyterlab/jupyterlab/releases/tag/v4.6.2
@krassowski krassowski published to jupyterlab/jupyterlab Jul 21, 2026
Published to the GitHub Advisory Database Jul 22, 2026
Reviewed Jul 22, 2026
Last updated Jul 22, 2026

Severity

Low

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
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
None

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:L/UI:N/S:U/C:N/I:N/A:N

EPSS score

Weaknesses

Improper Access Control

The product does not restrict or incorrectly restricts access to a resource from an unauthorized actor. Learn more on MITRE.

Not Failing Securely ('Failing Open')

When the product encounters an error condition or failure, its design requires it to fall back to a state that is less secure than other options that are available, such as selecting the weakest encryption algorithm or using the most permissive access control restrictions. Learn more on MITRE.

CVE ID

No known CVE

GHSA ID

GHSA-whvh-wf3x-g77j

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.