CVE-2024-35225 Overview
CVE-2024-35225 is a reflected cross-site scripting (XSS) vulnerability [CWE-79] in Jupyter Server Proxy, an extension that lets users run arbitrary external processes alongside their notebook server and expose them through authenticated web access. The /proxy/<host> endpoint reflects the host path segment back to the browser without sanitization when the value fails allowlist validation. An attacker can craft a phishing link containing JavaScript in the host segment. When a signed-in JupyterLab user clicks the link, the injected script executes in the context of their session.
Critical Impact
Successful exploitation grants the attacker script execution inside the victim's authenticated JupyterLab instance, enabling access to notebooks, kernels, and stored credentials.
Affected Products
- Jupyter Server Proxy 3.x versions prior to 3.2.4
- Jupyter Server Proxy 4.x versions prior to 4.2.0
- JupyterLab and Jupyter Server deployments using the vulnerable extension
Discovery Timeline
- 2024-06-11 - CVE-2024-35225 published to NVD
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2024-35225
Vulnerability Analysis
Jupyter Server Proxy validates the host path segment against an allowlist before proxying traffic. When validation fails, the handler in jupyter_server_proxy/handlers.py writes an error response back to the client that embeds the raw, attacker-controlled host value using Python string formatting. The response is served with an HTML-capable content type, so any markup or <script> tags contained in host are parsed and executed by the browser.
Because JupyterLab relies on same-origin trust for its REST and WebSocket APIs, injected JavaScript can call notebook endpoints, read files, spawn kernels, and execute arbitrary Python on the server. This turns a single click on a crafted URL into full access to the victim's compute environment. User interaction is required, which is reflected in the scoring, but no authentication of the attacker is needed.
Root Cause
The root cause is missing output encoding on a reflected path parameter. The pre-patch handler called self.set_status(403) followed by self.write("Host '{host}' is not allowed...".format(host=host)), placing untrusted input directly into the response body without HTML escaping.
Attack Vector
An attacker crafts a URL such as https://victim-jupyter.example/proxy/<img src=x onerror=fetch('/api/contents')> and delivers it via phishing. When the authenticated user opens the link, the browser renders the reflected payload and executes the script under the JupyterLab origin.
# Patch from jupyter_server_proxy/handlers.py
if not self._check_host_allowlist(host):
- self.set_status(403)
- self.write(
- "Host '{host}' is not allowed. "
- "See https://jupyter-server-proxy.readthedocs.io/en/latest/arbitrary-ports-hosts.html for info.".format(
- host=host
- )
- )
- return
+ raise web.HTTPError(
+ 403,
+ f"Host '{host}' is not allowed. "
+ "See https://jupyter-server-proxy.readthedocs.io/en/latest/arbitrary-ports-hosts.html for info.",
+ )
The fix replaces the raw self.write() call with web.HTTPError, which routes the message through Tornado's error handler and escapes the reflected value. Source: GitHub commit 7abc9dc.
Detection Methods for CVE-2024-35225
Indicators of Compromise
- Access log entries for GET /proxy/ requests where the <host> segment contains HTML metacharacters such as <, >, ", or URL-encoded equivalents (%3C, %3E).
- Referer headers pointing to external domains preceding /proxy/ requests with suspicious payloads.
- Outbound requests from browser sessions to unfamiliar /api/contents, /api/sessions, or /api/kernels endpoints shortly after a /proxy/<host> hit.
Detection Strategies
- Alert on HTTP GET requests to /proxy/* that return a 403 status and include script-like tokens (script, onerror, javascript:) in the URI.
- Deploy a Content Security Policy in report-only mode and monitor script-src violations originating from JupyterLab origins.
- Correlate JupyterHub authentication events with anomalous notebook API activity that follows a /proxy/ request within the same session.
Monitoring Recommendations
- Ingest reverse proxy, JupyterHub, and Jupyter Server access logs into a centralized log platform for retention and search.
- Track the installed version of jupyter-server-proxy across managed hubs to identify systems still running versions below 3.2.4 or 4.2.0.
- Review browser telemetry from user endpoints for unexpected JavaScript execution on Jupyter origins.
How to Mitigate CVE-2024-35225
Immediate Actions Required
- Upgrade jupyter-server-proxy to version 4.2.0 (4.x branch) or 3.2.4 (3.x branch) on every JupyterHub and standalone Jupyter deployment.
- Inventory all Jupyter environments, including container images and Binder deployments, to confirm the patched version is in use.
- Notify JupyterLab users to avoid clicking links to /proxy/ URLs from untrusted sources until patching is verified.
Patch Information
Patches are available in Jupyter Server Proxy 4.2.0 and 3.2.4. The fix is delivered in commits 7abc9dc and ff78128. See the GitHub Security Advisory GHSA-fvcq-4x64-hqxr for full details.
Workarounds
- Disable the jupyter-server-proxy extension where upgrading is not immediately possible.
- Restrict access to Jupyter deployments to trusted networks or require VPN and single sign-on to reduce phishing reach.
- Enforce a strict Content Security Policy that blocks inline script execution on JupyterLab origins.
# Upgrade jupyter-server-proxy to a patched release
pip install --upgrade "jupyter-server-proxy>=4.2.0"
# Or, for the 3.x branch
pip install --upgrade "jupyter-server-proxy>=3.2.4,<4"
# Temporary workaround: disable the extension
jupyter server extension disable jupyter_server_proxy
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

