mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-03 03:41:14 +08:00
Validate redirect target in TrailingSlashHandler
Fixes open redirect vulnerability GHSA-c7vm-f5p4-8fqh
This commit is contained in:
parent
5a73a8e402
commit
1abd95130c
@ -853,13 +853,18 @@ class APIVersionHandler(APIHandler):
|
||||
|
||||
class TrailingSlashHandler(web.RequestHandler):
|
||||
"""Simple redirect handler that strips trailing slashes
|
||||
|
||||
|
||||
This should be the first, highest priority handler.
|
||||
"""
|
||||
|
||||
|
||||
def get(self):
|
||||
self.redirect(self.request.uri.rstrip('/'))
|
||||
|
||||
path, *rest = self.request.uri.partition("?")
|
||||
# trim trailing *and* leading /
|
||||
# to avoid misinterpreting repeated '//'
|
||||
path = "/" + path.strip("/")
|
||||
new_uri = "".join([path, *rest])
|
||||
self.redirect(new_uri)
|
||||
|
||||
post = put = get
|
||||
|
||||
|
||||
@ -910,6 +915,7 @@ class RedirectWithParams(web.RequestHandler):
|
||||
url = sep.join([self._url, self.request.query])
|
||||
self.redirect(url, permanent=self._permanent)
|
||||
|
||||
|
||||
class PrometheusMetricsHandler(IPythonHandler):
|
||||
"""
|
||||
Return prometheus metrics for this notebook server
|
||||
|
@ -2,10 +2,13 @@
|
||||
import re
|
||||
|
||||
from notebook.base.handlers import path_regex
|
||||
from notebook.utils import url_path_join
|
||||
from .launchnotebook import NotebookTestBase
|
||||
|
||||
# build regexps that tornado uses:
|
||||
path_pat = re.compile('^' + '/x%s' % path_regex + '$')
|
||||
|
||||
|
||||
def test_path_regex():
|
||||
for path in (
|
||||
'/x',
|
||||
@ -29,3 +32,18 @@ def test_path_regex_bad():
|
||||
'/y/x/foo',
|
||||
):
|
||||
assert not re.match(path_pat, path)
|
||||
|
||||
|
||||
class RedirectTestCase(NotebookTestBase):
|
||||
def test_trailing_slash(self):
|
||||
for uri, expected in (
|
||||
("/notebooks/mynotebook/", "/notebooks/mynotebook"),
|
||||
("////foo///", "/foo"),
|
||||
("//example.com/", "/example.com"),
|
||||
("/has/param/?hasparam=true", "/has/param?hasparam=true"),
|
||||
):
|
||||
r = self.request("GET", uri, allow_redirects=False)
|
||||
print(uri, expected)
|
||||
assert r.status_code == 302
|
||||
assert "Location" in r.headers
|
||||
assert r.headers["Location"] == url_path_join(self.url_prefix, expected)
|
||||
|
Loading…
Reference in New Issue
Block a user