Jupyter Server's Origin header validation uses re.match() instead of re.fullmatch(), allowing any attacker who controls a domain starting with the trusted pattern (e.g., trusted.example.com.evil.com) to bypass CORS protections entirely. With 1,862 downstream dependents and Jupyter's near-universal presence in AI/ML development environments, this creates a wide cross-origin attack surface where a malicious web page can reach the Jupyter kernel API and execute arbitrary code against any unpatched instance — the EPSS places this in the top 87th percentile for exploitation likelihood despite low absolute probability. Patch to jupyter-server 2.18.0 immediately; if patching is not possible, anchor all allow_origin_pat values with ^ and $ as an interim workaround.
What is the risk?
HIGH risk for organizations where Jupyter Server is deployed on internal networks or developer workstations accessible from a browser. The vulnerability is straightforward to weaponize — an attacker needs only to register a domain that begins with the trusted prefix and serve a malicious page. Jupyter's kernel API permits arbitrary Python execution, so a successful CORS bypass grants effectively full code execution on the server with the process owner's privileges, making this a high-impact stepping stone into AI/ML development pipelines.
How does the attack unfold?
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| Jupyter | pip | <= 2.17.0 | 2.18.0 |
Do you use Jupyter? You're affected.
How severe is it?
What is the attack surface?
What should I do?
5 steps-
Patch: Upgrade jupyter-server to 2.18.0 (commits 057869a and 49b3439 resolve the issue).
-
Workaround: Immediately audit all allow_origin_pat configuration values and wrap each pattern with ^ and $ anchors (e.g., change trusted\.example\.com to ^trusted\.example\.com$).
-
Network controls: Restrict Jupyter Server access to localhost or trusted internal subnets; never expose Jupyter directly to the internet.
-
Audit dependents: Check whether downstream packages (JupyterLab, JupyterHub, notebook) in your environment pull jupyter-server <= 2.17.0 and upgrade those dependency chains.
-
Detection: Monitor web proxy and WAF logs for cross-origin requests to Jupyter endpoints (/api/kernels, /api/sessions) from unexpected origins.
What does CISA's SSVC say?
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
How is it classified?
Which compliance frameworks are affected?
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-40110?
Jupyter Server's Origin header validation uses re.match() instead of re.fullmatch(), allowing any attacker who controls a domain starting with the trusted pattern (e.g., trusted.example.com.evil.com) to bypass CORS protections entirely. With 1,862 downstream dependents and Jupyter's near-universal presence in AI/ML development environments, this creates a wide cross-origin attack surface where a malicious web page can reach the Jupyter kernel API and execute arbitrary code against any unpatched instance — the EPSS places this in the top 87th percentile for exploitation likelihood despite low absolute probability. Patch to jupyter-server 2.18.0 immediately; if patching is not possible, anchor all allow_origin_pat values with ^ and $ as an interim workaround.
Is CVE-2026-40110 actively exploited?
No confirmed active exploitation of CVE-2026-40110 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-40110?
1. Patch: Upgrade jupyter-server to 2.18.0 (commits 057869a and 49b3439 resolve the issue). 2. Workaround: Immediately audit all allow_origin_pat configuration values and wrap each pattern with ^ and $ anchors (e.g., change trusted\.example\.com to ^trusted\.example\.com$). 3. Network controls: Restrict Jupyter Server access to localhost or trusted internal subnets; never expose Jupyter directly to the internet. 4. Audit dependents: Check whether downstream packages (JupyterLab, JupyterHub, notebook) in your environment pull jupyter-server <= 2.17.0 and upgrade those dependency chains. 5. Detection: Monitor web proxy and WAF logs for cross-origin requests to Jupyter endpoints (/api/kernels, /api/sessions) from unexpected origins.
What systems are affected by CVE-2026-40110?
This vulnerability affects the following AI/ML architecture patterns: ML development environments, Training pipelines using notebook orchestration, JupyterHub multi-user deployments, MLOps pipelines with programmatic notebook execution, Data science workstations with browser-accessible Jupyter.
What is the CVSS score for CVE-2026-40110?
CVE-2026-40110 has a CVSS v3.1 base score of 7.1 (HIGH). The EPSS exploitation probability is 0.34%.
What is the AI security impact?
Affected AI Architectures
MITRE ATLAS Techniques
AML.T0008.002 Domains AML.T0025 Exfiltration via Cyber Means AML.T0035 AI Artifact Collection AML.T0049 Exploit Public-Facing Application Compliance Controls Affected
What are the technical details?
Original Advisory
Jupyter Server is the backend for Jupyter web applications. In versions 2.17.0 and earlier, the Origin header validation uses Python's re.match() to check incoming origins against the allow_origin_pat configuration value. Because re.match() only anchors at the start of the string and does not require a full match, a pattern intended to match only a trusted domain (e.g., trusted.example.com) will also match any origin that begins with that domain followed by additional characters (e.g., trusted.example.com.evil.com). An attacker who controls such a domain can bypass the CORS origin restriction and make cross-origin requests to the Jupyter Server API from an untrusted site. This issue has been fixed in version 2.18.0.
Exploitation Scenario
An adversary targeting an AI development team registers trusted.example.com.evil.com — a domain crafted to match the victim's allow_origin_pat regex at the start while appending an attacker-controlled suffix. They deploy a malicious page on this domain with JavaScript that fetches the list of active Jupyter kernels (GET /api/kernels), selects one, and posts an execute request (POST /api/kernels/<id>/execute) containing Python code to read notebook files, harvest embedded cloud API keys or model registry tokens, and exfiltrate them to the attacker's infrastructure. A targeted phishing email lures a developer to visit the malicious page; since the browser sends the crafted Origin header and Jupyter's re.match() check passes, CORS headers are returned, the browser lifts the same-origin restriction, and the JavaScript silently exfiltrates the environment's AI artifacts without any user interaction beyond the initial page load.
Weaknesses (CWE)
CWE-777 — Regular Expression without Anchors: The product uses a regular expression to perform neutralization, but the regular expression is not anchored and may allow malicious or malformed data to slip through.
- [Implementation] Be sure to understand both what will be matched and what will not be matched by a regular expression. Anchoring the ends of the expression will allow the programmer to define an allowlist strictly limited to what is matched by the text in the regular expression. If you are using a package that only matches one line by default, ensure that you can match multi-line inputs if necessary.
Source: MITRE CWE corpus.
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:L/A:N References
- github.com/jupyter-server/jupyter_server/commit/057869a327c46730afede3eab0ca2d2e3e74acea x_refsource_MISC
- github.com/jupyter-server/jupyter_server/commit/49b34392feaa97735b3b777e3baf8f22f2a14ed8 x_refsource_MISC
- github.com/jupyter-server/jupyter_server/pull/603 x_refsource_MISC
- github.com/advisories/GHSA-24qx-w28j-9m6p
- github.com/jupyter-server/jupyter_server/security/advisories/GHSA-24qx-w28j-9m6p
Timeline
Related Vulnerabilities
CVE-2023-25574 10.0 JupyterHub LTI13: JWT forgery enables full auth bypass
Same package: jupyter CVE-2026-44180 9.8 Jupyter Enterprise Gateway: root privilege bypass in Kubernetes
Same package: jupyter CVE-2026-23537 9.1 Feast: unauth file write to RCE via /save-document
Same package: jupyter CVE-2026-44727 9.0 jupyter-server: stored XSS yields kernel RCE
Same package: jupyter CVE-2026-42557 8.8 JupyterLab: one-click RCE via notebook HTML cell output
Same package: jupyter