GHSA-354v-3q48-cv69: High severity pip/jupyter-server vulnerability

Published Oct 22, 2026
·
Updated

Summary

Jupyter Server's gateway WebSocket handler checks that a user is authenticated, but it does not ask the configured Authorizer whether that user may execute kernels.

In Jupyter Server 2.0.0 through 2.5.0, enabling GatewayClient.url automatically replaced the normal kernel channel handler with this gateway-specific handler. An authenticated user who is denied the execute action on the kernels resource can therefore still open a kernel channel and send messages to the upstream kernel.

Details

The normal handler performs the expected authorization check before creating the WebSocket connection:

https://github.com/jupyter-server/jupyterserver/blob/v2.5.0/jupyterserver/services/kernels/websocket.py#L39-L47

The gateway handler only checks currentuser and then opens the upstream channel. It never calls authorizer.isauthorized(...):

https://github.com/jupyter-server/jupyterserver/blob/v2.5.0/jupyterserver/gateway/handlers.py#L49-L75 https://github.com/jupyter-server/jupyterserver/blob/v2.5.0/jupyterserver/gateway/handlers.py#L87-L98

Gateway mode selected that handler automatically by replacing handlers with matching routes:

https://github.com/jupyter-server/jupyterserver/blob/v2.5.0/jupyterserver/serverapp.py#L437-L446

PR #1261 stopped replacing the normal handler and routed gateway traffic through GatewayWebSocketConnection instead. This appears to have fixed the default gateway configuration in 2.6.0, although the deprecated handler is still present in current releases and can still be registered directly.

https://github.com/jupyter-server/jupyterserver/pull/1261

Code-level validation

1. Configure a custom Authorizer that returns false for execute on kernels for a regular authenticated user. 2. Configure GatewayClient.url on Jupyter Server 2.0.0-2.5.0. 3. The normal KernelWebsocketHandler would reject that user with 403 in preget. 4. Gateway mode replaces it with WebSocketChannelsHandler. Its authenticate method only rejects anonymous users, and get proceeds to the upstream gateway without an authorization decision.

Impact

This is a missing authorization check, not an authentication bypass. It matters in deployments that use a restrictive custom Authorizer and Jupyter Gateway/Enterprise Gateway. A read-only or otherwise limited authenticated user can cross the intended authorization boundary and obtain kernel execution, with access to data and credentials available to that kernel.

Affected versions

- Default gateway configuration: 2.0.0 through 2.5.0 - 2.6.0 and later: the default path uses the authorized standard handler, but manually registering the deprecated jupyterserver.gateway.handlers module still exposes the old behavior.

Affected Software

1 affected componentFixes available
pip/jupyter-server>=2.0.0<2.6.0
2.6.0

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/jupyter-server to a version that resolves this vulnerability.

    Fixed in 2.6.0
  2. Upgrade

    Upgrade jupyter-server to a version that resolves this vulnerability.

    Fixed in 2.6.0
  3. Configuration

    Do not manually register the deprecated jupyter_server.gateway.handlers module, which still exposes the old behavior.

    Jupyter Server jupyter_server.gateway.handlers module registration = disabled

Event History

Oct 22, 2026
Advisory Published
via GitHub·03:46 PM
Data Sourced
via GitHub·03:46 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are affected?

Deployments running Jupyter Server versions 2.0.0 through 2.5.0 are affected when GatewayClient.url is enabled. Enabling that setting automatically selects the gateway-specific kernel channel handler.

2

What access does an attacker need?

The attacker must be authenticated to Jupyter Server. They do not need permission for the execute action on the kernels resource, because the gateway WebSocket handler does not consult the configured Authorizer.

3

What can a successful attacker do?

An authenticated but execution-denied user can open a kernel channel and send messages to the upstream kernel. This bypasses the intended kernel execution authorization control.

4

How can I determine whether my instance is exposed?

Check whether Jupyter Server is between versions 2.0.0 and 2.5.0 and whether GatewayClient.url is configured. Exposure is especially relevant where the Authorizer denies some authenticated users the execute action on kernels.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203