From e111a876f76c637029afc2fbeb58726cbdf11367 Mon Sep 17 00:00:00 2001 From: cato447 Date: Fri, 20 Feb 2026 03:27:42 +0100 Subject: [PATCH] added url check --- app/routes.py | 9 +++++++++ app/utils.py | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/app/routes.py b/app/routes.py index eacc4eb..0be81eb 100644 --- a/app/routes.py +++ b/app/routes.py @@ -41,6 +41,7 @@ from .utils import ( get_course, token_required, get_cached_deck_info, + is_safe_url ) @@ -131,6 +132,10 @@ def set_cookie(token): current_app.logger.debug("next_url not present redirecting to index") next_url = url_for("main.index") + if not is_safe_url(next_url): + current_app.logger.warning(f"Blocked unsafe redirect attempt to: {next_url}") + return abort(400) + resp = make_response(redirect(next_url)) resp.set_cookie( "access_token", serialize_token(token), httponly=True, samesite="Lax", path="/" @@ -260,6 +265,10 @@ def admin_login(): next_page = request.args.get("next") + if next_page and not is_safe_url(next_page): + current_app.logger.warning(f"Blocked unsafe redirect attempt to: {next_page}") + return abort(400) + if next_page: session["next_url"] = next_page diff --git a/app/utils.py b/app/utils.py index a1e33e1..143b122 100644 --- a/app/utils.py +++ b/app/utils.py @@ -6,6 +6,7 @@ from typing import cast from itsdangerous import BadSignature, URLSafeSerializer from xkcdpass import xkcd_password from functools import wraps, lru_cache +from urllib.parse import urlparse, urljoin from .models import Deck, InfoBanner, Token, db, Course @@ -209,3 +210,13 @@ def get_cached_deck_info(token_id, course_folder, deck_slug): "deck_name": deck_obj.name, "index_file": deck_obj.index_file } + +def is_safe_url(target): + """ + Ensures that a redirect target will lead to the same server. + Handles both relative paths ('/admin') and absolute URLs ('https://yourdomain.com/admin'). + """ + ref_url = urlparse(request.host_url) + test_url = urlparse(urljoin(request.host_url, target)) + + return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc