diff --git a/cms/server/admin/handlers/main.py b/cms/server/admin/handlers/main.py index e3ce0760aa..ba85fee6d1 100644 --- a/cms/server/admin/handlers/main.py +++ b/cms/server/admin/handlers/main.py @@ -27,6 +27,7 @@ import json import logging +from urllib.parse import urlsplit from cms import ServiceCoord, get_service_shards, get_service_address from cms.db import Admin, Contest, Question @@ -48,10 +49,22 @@ def post(self): next_page: str = self.get_argument("next", None) if next_page is not None: error_args["next"] = next_page - if next_page != "/": - next_page = self.url(*next_page.strip("/").split("/")) + split = urlsplit(next_page) + path = split.path or "/" + if split.scheme or split.netloc or not path.startswith("/"): + next_page = self.url() + elif path != "/": + path_segments = path.strip("/").split("/") + if any(segment in ("", ".", "..") for segment in path_segments): + next_page = self.url() + else: + next_page = self.url(*path_segments) + if split.query: + next_page += "?" + split.query else: next_page = self.url() + if split.query: + next_page += "?" + split.query else: next_page = self.url() error_page = self.url("login", **error_args) diff --git a/cms/server/contest/handlers/main.py b/cms/server/contest/handlers/main.py index 93402e2b0c..fb0111101e 100644 --- a/cms/server/contest/handlers/main.py +++ b/cms/server/contest/handlers/main.py @@ -33,6 +33,7 @@ import logging import os.path import re +from urllib.parse import urlsplit import collections @@ -217,10 +218,22 @@ def post(self): next_page: str | None = self.get_argument("next", None) if next_page is not None: error_args["next"] = next_page - if next_page != "/": - next_page = self.url(*next_page.strip("/").split("/")) + split = urlsplit(next_page) + path = split.path or "/" + if split.scheme or split.netloc or not path.startswith("/"): + next_page = self.contest_url() + elif path != "/": + path_segments = path.strip("/").split("/") + if any(segment in ("", ".", "..") for segment in path_segments): + next_page = self.contest_url() + else: + next_page = self.url(*path_segments) + if split.query: + next_page += "?" + split.query else: next_page = self.url() + if split.query: + next_page += "?" + split.query else: next_page = self.contest_url() error_page = self.contest_url(**error_args)