CVE-2019-10856
Description
In Jupyter Notebook before 5.7.8, an open redirect can occur via an empty netloc. This issue exists because of an incomplete fix for CVE-2019-10255.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
In Jupyter Notebook before 5.7.8, an open redirect vulnerability exists due to an incomplete fix for CVE-2019-10255, allowing attacks via an empty netloc.
Vulnerability
Analysis
CVE-2019-10856 is an open redirect vulnerability in Jupyter Notebook, affecting versions prior to 5.7.8. The root cause lies in an incomplete fix for a previously identified open redirect issue, CVE-2019-10255. Specifically, the vulnerability can be triggered by providing an empty network location (netloc) in a URL, which the notebook server fails to properly validate, leading to a redirect to an attacker-controlled external site [1].
Exploitation
The attack surface is through crafted URLs that exploit the empty netloc condition. An attacker can trick a user into clicking a malicious link that appears to be hosted on the legitimate Jupyter Notebook server, but due to the improper handling, the user is redirected to an external, potentially malicious site. No authentication is required beyond the user's interaction with the link, making this a client-side attack vector [1][2].
Impact
Successful exploitation allows an attacker to redirect users to arbitrary external domains. This can be used for phishing attacks, where users are directed to fake login pages, or to deliver malware through drive-by downloads. The open redirect can also be leveraged to bypass URL-based security filters or to steal sensitive information such as session tokens or credentials [1].
Mitigation
The vulnerability is fixed in Jupyter Notebook version 5.7.8. Users running earlier versions (including 5.7.7 and below) are strongly advised to upgrade to the latest release. The Notebook v5 series is no longer maintained; upgrading to a supported major version (v6 or v7) is recommended for continued security updates [2][3].
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
notebookPyPI | < 5.7.8 | 5.7.8 |
Affected products
2Patches
1979e0bd15e79even more careful with login redirect checks
2 files changed · +16 −7
notebook/auth/login.py+8 −5 modified@@ -7,9 +7,9 @@ import os try: - from urllib.parse import urlparse # Py 3 + from urllib.parse import urlparse, urlunparse # Py 3 except ImportError: - from urlparse import urlparse # Py 2 + from urlparse import urlparse, urlunparse # Py 2 import uuid from tornado.escape import url_escape @@ -44,15 +44,18 @@ def _redirect_safe(self, url, default=None): # instead of %5C, causing `\\` to behave as `//` url = url.replace("\\", "%5C") parsed = urlparse(url) - if parsed.netloc or not (parsed.path + '/').startswith(self.base_url): + path_only = urlunparse(parsed._replace(netloc='', scheme='')) + if url != path_only or not (parsed.path + '/').startswith(self.base_url): # require that next_url be absolute path within our path allow = False # OR pass our cross-origin check - if parsed.netloc: + if url != path_only: # if full URL, run our cross-origin check: origin = '%s://%s' % (parsed.scheme, parsed.netloc) origin = origin.lower() - if self.allow_origin: + if origin == '%s://%s' % (self.request.protocol, self.request.host): + allow = True + elif self.allow_origin: allow = self.allow_origin == origin elif self.allow_origin_pat: allow = bool(self.allow_origin_pat.match(origin))
notebook/auth/tests/test_login.py+8 −2 modified@@ -31,6 +31,8 @@ def test_next_bad(self): "//host" + self.url_prefix + "tree", "https://google.com", "/absolute/not/base_url", + "///jupyter.org", + "/\\some-host", ): url = self.login(next=bad_next) self.assertEqual(url, self.url_prefix) @@ -39,10 +41,14 @@ def test_next_bad(self): def test_next_ok(self): for next_path in ( "tree/", - "//" + self.url_prefix + "tree", + self.base_url() + "has/host", "notebooks/notebook.ipynb", "tree//something", ): - expected = self.url_prefix + next_path + if "://" in next_path: + expected = next_path + else: + expected = self.url_prefix + next_path + actual = self.login(next=expected) self.assertEqual(actual, expected)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-rcx2-m7jp-p9wjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2019-10856ghsaADVISORY
- blog.jupyter.org/open-redirect-vulnerability-in-jupyter-jupyterhub-adf43583f1e4ghsax_refsource_MISCWEB
- github.com/jupyter/notebook/commit/979e0bd15e794ceb00cc63737fcd5fd9addc4a99ghsaWEB
- github.com/jupyter/notebook/compare/16cf97c...b8e30eaghsax_refsource_MISCWEB
- github.com/pypa/advisory-database/tree/main/vulns/notebook/PYSEC-2019-158.yamlghsaWEB
News mentions
0No linked articles in our index yet.