VYPR
Moderate severityOSV Advisory· Published Apr 4, 2019· Updated Aug 4, 2024

CVE-2019-10856

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.

PackageAffected versionsPatched versions
notebookPyPI
< 5.7.85.7.8

Affected products

2

Patches

1
979e0bd15e79

even more careful with login redirect checks

https://github.com/jupyter/notebookMin RKApr 1, 2019via ghsa
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

News mentions

0

No linked articles in our index yet.