Skip to content

Commit b981c5b

Browse files
committed
Merge branch 'check-redirect-target'
2 parents 35ac42b + 08c4c89 commit b981c5b

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

docs/source/changelog.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,21 @@ We strongly recommend that you upgrade pip to version 9+ of pip before upgrading
3131
- Further improve compatibility with tornado 6 with improved
3232
checks for when websockets are closed.
3333
- Fix regression in 5.7.6 on Windows where .js files could have the wrong mime-type.
34+
- Fix Open Redirect vulnerability where certain malicious URLs could redirect from the Jupyter login page to a malicious site after a successful login. A CVE has been requested for this vulnerability.
3435

3536
.. _release-5.7.6:
3637

3738
5.7.6
3839
-----
3940

40-
5.7.6 contains a security fix for a cross-site inclusion (XSSI) vulnerability,
41+
5.7.6 contains a security fix for a cross-site inclusion (XSSI) vulnerability (CVE-2019–9644),
4142
where files at a known URL could be included in a page from an unauthorized website if the user is logged into a Jupyter server.
4243
The fix involves setting the ``X-Content-Type-Options: nosniff``
4344
header, and applying CSRF checks previously on all non-GET
4445
API requests to GET requests to API endpoints and the /files/ endpoint.
4546

4647
The attacking page is able to access some contents of files when using Internet Explorer through script errors,
4748
but this has not been demonstrated with other browsers.
48-
A CVE has been requested for this vulnerability.
4949

5050
.. _release-5.7.5:
5151

notebook/auth/login.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,19 @@ def _redirect_safe(self, url, default=None):
3939
"""
4040
if default is None:
4141
default = self.base_url
42-
if not url.startswith(self.base_url):
42+
# protect chrome users from mishandling unescaped backslashes.
43+
# \ is not valid in urls, but some browsers treat it as /
44+
# instead of %5C, causing `\\` to behave as `//`
45+
url = url.replace("\\", "%5C")
46+
parsed = urlparse(url)
47+
if parsed.netloc or not (parsed.path + '/').startswith(self.base_url):
4348
# require that next_url be absolute path within our path
4449
allow = False
4550
# OR pass our cross-origin check
46-
if '://' in url:
51+
if parsed.netloc:
4752
# if full URL, run our cross-origin check:
48-
parsed = urlparse(url.lower())
4953
origin = '%s://%s' % (parsed.scheme, parsed.netloc)
54+
origin = origin.lower()
5055
if self.allow_origin:
5156
allow = self.allow_origin == origin
5257
elif self.allow_origin_pat:

notebook/auth/tests/test_login.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Tests for login redirects"""
2+
3+
import requests
4+
from tornado.httputil import url_concat
5+
6+
from notebook.tests.launchnotebook import NotebookTestBase
7+
8+
9+
class LoginTest(NotebookTestBase):
10+
def login(self, next):
11+
first = requests.get(self.base_url() + "login")
12+
first.raise_for_status()
13+
resp = requests.post(
14+
url_concat(
15+
self.base_url() + "login",
16+
{'next': next},
17+
),
18+
allow_redirects=False,
19+
data={
20+
"password": self.token,
21+
"_xsrf": first.cookies.get("_xsrf", ""),
22+
},
23+
cookies=first.cookies,
24+
)
25+
resp.raise_for_status()
26+
return resp.headers['Location']
27+
28+
def test_next_bad(self):
29+
for bad_next in (
30+
"//some-host",
31+
"//host" + self.url_prefix + "tree",
32+
"https://google.com",
33+
"/absolute/not/base_url",
34+
):
35+
url = self.login(next=bad_next)
36+
self.assertEqual(url, self.url_prefix)
37+
assert url
38+
39+
def test_next_ok(self):
40+
for next_path in (
41+
"tree/",
42+
"//" + self.url_prefix + "tree",
43+
"notebooks/notebook.ipynb",
44+
"tree//something",
45+
):
46+
expected = self.url_prefix + next_path
47+
actual = self.login(next=expected)
48+
self.assertEqual(actual, expected)

0 commit comments

Comments
 (0)