Only redirect to sanitized path under /web
This commit is contained in:
parent
d1532aa466
commit
4ed77cabc6
@ -193,12 +193,6 @@ class Application(ApplicationPartDelete, ApplicationPartHead,
|
|||||||
# Sanitize request URI (a WSGI server indicates with an empty path,
|
# Sanitize request URI (a WSGI server indicates with an empty path,
|
||||||
# that the URL targets the application root without a trailing slash)
|
# that the URL targets the application root without a trailing slash)
|
||||||
path = pathutils.sanitize_path(unsafe_path)
|
path = pathutils.sanitize_path(unsafe_path)
|
||||||
if unsafe_path != path and request_method in ["GET", "HEAD"]:
|
|
||||||
location = base_prefix + path
|
|
||||||
logger.info("Redirecting to sanitized path: %r ==> %r",
|
|
||||||
base_prefix + unsafe_path, location)
|
|
||||||
return response(*httputils.redirect(
|
|
||||||
location, client.MOVED_PERMANENTLY))
|
|
||||||
logger.debug("Sanitized path: %r", path)
|
logger.debug("Sanitized path: %r", path)
|
||||||
|
|
||||||
# Get function corresponding to method
|
# Get function corresponding to method
|
||||||
|
@ -60,11 +60,18 @@ class ApplicationPartGet(ApplicationBase):
|
|||||||
def do_GET(self, environ: types.WSGIEnviron, base_prefix: str, path: str,
|
def do_GET(self, environ: types.WSGIEnviron, base_prefix: str, path: str,
|
||||||
user: str) -> types.WSGIResponse:
|
user: str) -> types.WSGIResponse:
|
||||||
"""Manage GET request."""
|
"""Manage GET request."""
|
||||||
# Redirect to .web if the root URL is requested
|
# Redirect to /.web if the root path is requested
|
||||||
if not pathutils.strip_path(path):
|
if not pathutils.strip_path(path):
|
||||||
return httputils.redirect(".web")
|
return httputils.redirect(base_prefix + "/.web")
|
||||||
# Dispatch .web URL to web module
|
|
||||||
if path == "/.web" or path.startswith("/.web/"):
|
if path == "/.web" or path.startswith("/.web/"):
|
||||||
|
# Redirect to sanitized path for all subpaths of /.web
|
||||||
|
unsafe_path = environ.get("PATH_INFO", "")
|
||||||
|
if unsafe_path != path:
|
||||||
|
location = base_prefix + path
|
||||||
|
logger.info("Redirecting to sanitized path: %r ==> %r",
|
||||||
|
base_prefix + unsafe_path, location)
|
||||||
|
return httputils.redirect(location, client.MOVED_PERMANENTLY)
|
||||||
|
# Dispatch /.web path to web module
|
||||||
return self._web.get(environ, base_prefix, path, user)
|
return self._web.get(environ, base_prefix, path, user)
|
||||||
access = Access(self._rights, user, path)
|
access = Access(self._rights, user, path)
|
||||||
if not access.check("r") and "i" not in access.permissions:
|
if not access.check("r") and "i" not in access.permissions:
|
||||||
|
@ -53,26 +53,28 @@ permissions: RrWw""")
|
|||||||
|
|
||||||
def test_root(self) -> None:
|
def test_root(self) -> None:
|
||||||
"""GET request at "/"."""
|
"""GET request at "/"."""
|
||||||
status, headers, answer = self.request("GET", "/", check=302)
|
for path in ["", "/", "//"]:
|
||||||
assert headers.get("Location") == ".web"
|
_, headers, answer = self.request("GET", path, check=302)
|
||||||
assert answer == "Redirected to .web"
|
assert headers.get("Location") == "/.web"
|
||||||
|
assert answer == "Redirected to /.web"
|
||||||
|
|
||||||
def test_root_script_name(self) -> None:
|
def test_root_script_name(self) -> None:
|
||||||
"""GET request at "/" with SCRIPT_NAME."""
|
"""GET request at "/" with SCRIPT_NAME."""
|
||||||
_, answer = self.get("/", check=302, SCRIPT_NAME="/radicale")
|
for path in ["", "/", "//"]:
|
||||||
assert answer == "Redirected to .web"
|
_, headers, _ = self.request("GET", path, check=302,
|
||||||
|
SCRIPT_NAME="/radicale")
|
||||||
|
assert headers.get("Location") == "/radicale/.web"
|
||||||
|
|
||||||
def test_sanitized_path(self) -> None:
|
def test_sanitized_path(self) -> None:
|
||||||
"""GET request with unsanitized paths."""
|
"""GET request with unsanitized paths."""
|
||||||
for path, sane_path in [("//", "/"), ("", "/"), ("/a//b", "/a/b"),
|
for path, sane_path in [
|
||||||
("/a//b/", "/a/b/")]:
|
("//.web", "/.web"), ("//.web/", "/.web/"),
|
||||||
_, headers, answer = self.request("GET", path, check=301)
|
("/.web//", "/.web/"), ("/.web/a//b", "/.web/a/b")]:
|
||||||
|
_, headers, _ = self.request("GET", path, check=301)
|
||||||
assert headers.get("Location") == sane_path
|
assert headers.get("Location") == sane_path
|
||||||
assert answer == "Redirected to %s" % sane_path
|
_, headers, _ = self.request("GET", path, check=301,
|
||||||
_, headers, answer = self.request("GET", path, check=301,
|
|
||||||
SCRIPT_NAME="/radicale")
|
SCRIPT_NAME="/radicale")
|
||||||
assert headers.get("Location") == "/radicale%s" % sane_path
|
assert headers.get("Location") == "/radicale%s" % sane_path
|
||||||
assert answer == "Redirected to /radicale%s" % sane_path
|
|
||||||
|
|
||||||
def test_add_event(self) -> None:
|
def test_add_event(self) -> None:
|
||||||
"""Add an event."""
|
"""Add an event."""
|
||||||
|
Loading…
Reference in New Issue
Block a user