GitHub Advisoryadvisory · PyPI
GHSA-w3vc-fx9p-wp4v Jupyter Server Proxy's Websocket Proxying does not require authentication
CRITICAL
Official page ↗
- Aliases
- CVE-2024-28179
- Ecosystem
- PyPI
- Packages
- jupyter-server-proxy
- Severity
- Critical
- CVSS vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
- Weaknesses
- CWE-306
- Reviewed
- 2024-03-20
Affected packages
• PyPI jupyter-server-proxy: >= 4.0.0, < 4.1.1 → fixed in 4.1.1
• PyPI jupyter-server-proxy: < 3.2.3 → fixed in 3.2.3
Description
Summary
`jupyter-server-proxy` is used to expose ports local to a Jupyter server listening to web traffic to the Jupyter server's _authenticated users_ by proxying web requests and websockets. Dependent packages (partial list) also use `jupyter-server-proxy` to expose other popular interactive applications (such as RStudio, Linux Desktop via VNC, Code Server, Panel, etc) along with the Jupyter server. This feature is commonly used in hosted environments (such as a JupyterHub) to expose non-Jupyter interactive frontends or APIs to the user.
`jupyter-server-proxy` did not check user authentication appropriately when proxying websockets, allowing unauthenticated access to anyone who had network access to the Jupyter server endpoint.
Impact
This vulnerability can allow unauthenticated remote access to any websocket endpoint set up to be accessible via `jupyter-server-proxy`. In many cases (such as when exposing RStudio via `jupyter-rsession-proxy` or a remote Linux Desktop / VNC via `jupyter-remote-desktop-proxy`), this leads to remote unauthenticated arbitrary code execution, due to how they use websockets. The websocket endpoints exposed by `jupyter_server` itself is not affected. Projects that do not rely on websockets are also not affected.
Remediation
Upgrade `jupyter-server-proxy` to a patched version and restart any running Jupyter server.
You may not be installing `jupyter-server-proxy` directly, but have it be pulled in as a dependency (partial list of dependent packages) - so you may be vulnerable even if you aren't directly depending on `jupyter-server-proxy`.
For JupyterHub admins of [TLJH] installations
Expand to read more
To secure a tljh deployment's user servers, first check if `jupyter-server-proxy` is installed in the user environment with a vulnerable version. If it is, patch the vulnerability and consider terminating currently running user servers.
[tljh]: https://tljh.jupyter.org
1. Check for vulnerability
As an JupyterHub admin from a terminal in a started user server, you can do:
```bash
sudo -E python3 -c '
try:
import jupyter_server_proxy
is_vulnerable = not hasattr(jupyter_server_proxy, "__version__")
except:
is_vulnerable = False
if is_vulnerable:
print("WARNING: jupyter-server-proxy __is vulnerable__ to GHSA-w3vc-fx9p-wp4v, see https://github.com/jupyterhub/jupyter-server-proxy/security/advisories/GHSA-w3vc-fx9p-wp4v.")
else:
print("INFO: not vulnerable to GHSA-w3vc-fx9p-wp4v")
'
```
Alternatively as a root user on the server where tljh is installed, you can do:
```bash
sudo PATH=/opt/tljh/user/bin:${PATH} python3 -c '
try:
import jupyter_server_proxy
is_vulnerable = not hasattr(jupyter_server_proxy, "__version__")
except:
is_vulnerable = False
if is_vulnerable:
print("WARNING: jupyter-server-proxy __is vulnerable__ to GHSA-w3vc-fx9p-wp4v, see https://github.com/jupyterhub/jupyter-server-proxy/security/advisories/GHSA-w3vc-fx9p-wp4v.")
else:
print("INFO: not vulnerable to GHSA-w3vc-fx9p-wp4v")
'
```
2. Patch detected vulnerability
As an JupyterHub admin from a terminal in a started user server, you can do:
```bash
sudo -E pip install "jupyter-server-proxy>=3.2.3,!=4.0.0,!=4.1.0"
```
Alternatively as a root user on the server where tljh is installed, you can do:
```bash
sudo PATH=/opt/tljh/user/bin:${PATH} pip install "jupyter-server-proxy>=3.2.3,!=4.0.0,!=4.1.0"
```
3. Consider terminating currently running user servers
User servers that started before the patch was applied are still vulnerable. To ensure they aren't vulnerable any more you could forcefully terminate their servers via the JupyterHub web interface at `https:///hub/admin`.
For JupyterHub admins of [Z2JH] installations
Expand to read more
To secure your z2jh deployment's user servers, first consider if one or more user environments is or may be vulnerable, then ensure new user servers' aren't started with the vulnerability, and finally consider terminating currently running user servers. The steps below guide you to do so.
[z2jh]: https://z2jh.jupyter.org
1. Check for vulnerabilities
Consider all docker images that user servers' environment may be based on. If your deployment expose a fixed set of images, you may be able to update them to non-vulnerable versions.
To check if an individual docker image is vulnerable, use a command like:
```bash
CHECK_IMAGE=jupyter/base-notebook:2023-10-20
docker run --rm $CHECK_IMAGE python3 -c '
try:
import jupyter_server_proxy
is_vulnerable = not hasattr(jupyter_server_proxy, "__version__")
except:
is_vulnerable = False
if is_vulnerable:
print("WARNING: jupyter-server-proxy __is vulnerable__ to GHSA-w3vc-fx9p-wp4v, see https://github.com/jupyterhub/jupyter-server-proxy/security/advisories/GHSA-w3vc-fx9p-wp4v.")
else:
print("INFO: not vulnerable to GHSA-w3vc-fx9p-wp4v")
'
```
Note that if you reference an image with a mutable tag, such as `quay.io/jupyter/pangeo-notebook:master`, you should ensure a new version is used by configuring the image pull policy so that an older vulnerable version isn't kept being used because it was already available on a Kubernetes node.
```yaml
singleuser:
image:
name: quay.io/jupyter/pangeo-notebook
tag: master
# pullPolicy (a.k.a. imagePullPolicy in k8s specification) should be
# declared to Always if you make use of mutable tags
pullPolicy: Always
```
2. Patch vulnerabilities dynamically
If your z2jh deployment still may start vulnerable images for users, you could mount a script that checks and patches the vulnerability before the jupyter server starts.
Below is JupyterHub Helm chart configuration that relies on [`singleuser.extraFiles`] and [`singleuser.cmd`] to mount a script we use as an entrypoint to dynamically check and patch the vulnerability before jupyter server is started.
Unless you change it, the script will attempt to upgrade `jupyter-server-proxy` to a non-vulnerable version if needed, and error if it needs to and fails. You can adjust this behavior by adjusting the constants `UPGRADE_IF_VULNERABLE` and `ERROR_IF_VULNERABLE` inside the script.
[`singleuser.extraFiles`]: https://z2jh.jupyter.org/en/stable/resources/reference.html#singleuser-extrafiles
[`singleuser.cmd`]: https://z2jh.jupyter.org/en/stable/resources/reference.html#singleuser-cmd
```yaml
singleuser:
cmd:
• /mnt/ghsa-w3vc-fx9p-wp4v/check-patch-run
• jupyterhub-singleuser
extraFiles:
ghsa-w3vc-fx9p-wp4v-check-patch-run:
mountPath: /mnt/ghsa-w3vc-fx9p-wp4v/check-patch-run
mode: 0755
stringData: |
#!/usr/bin/env python3
"""
This script is designed to check for and conditionally patch GHSA-w3vc-fx9p-wp4v
in user servers started by a JupyterHub. The script will execute any command
passed via arguments if provided, allowing it to wrap a user server startup call
to `jupyterhub-singleuser` for example.
Use and function of this script can be further discussed in
https://github.com/jupyterhub/zero-to-jupyterhub-k8s/issues/3360.
Script adjustments:
• UPGRADE_IF_VULNERABLE
• ERROR_IF_VULNERABLE
Script patching assumptions:
• script is run before the jupyter server starts
• pip is available
• pip has sufficient filesystem permissions to upgrade jupyter-server-proxy
Read more at https://github.com/jupyterhub…
Related
Alias · CVE (1)
- CVE-2024-28179 Jupyter Server Proxy allows users to run arbitrary external processes alongside their Jupyter notebook servers and provides authenticated… vulnerability
Weakness · CWE (1)
- CWE-306 Missing Authentication for Critical Functionality weakness
References
- https://github.com/jupyterhub/jupyter-server-proxy/security/advisories/GHSA-w3vc-fx9p-wp4v web
- https://nvd.nist.gov/vuln/detail/CVE-2024-28179 advisory
- https://github.com/jupyterhub/jupyter-server-proxy/commit/764e499f61a87641916a7a427d4c4b1ac3f321a9 web
- https://github.com/jupyterhub/jupyter-server-proxy/commit/bead903b7c0354b6efd8b4cde94b89afab653e03 web
- https://github.com/jupyterhub/jupyter-server-proxy package
- https://github.com/jupyterhub/jupyter-server-proxy/blob/9b624c4d9507176334b46a85d94a4aa3bcd29bed/jupyter_server_proxy/handlers.py#L433 web
- https://github.com/pypa/advisory-database/tree/main/vulns/jupyter-server-proxy/PYSEC-2024-234.yaml web