From 8bb1c0838b034b6294c9cc778d0f9c2a4cd87faf Mon Sep 17 00:00:00 2001 From: Semgrep Autofix Date: Tue, 17 Mar 2026 09:50:31 +0000 Subject: [PATCH] Fix open redirect vulnerability in login_and_redirect endpoint Fix open redirect vulnerability by validating and sanitizing the redirect URL using urlparse(). ## Changes - Parse the user-provided URL with `urlparse()` before use - Validate that the URL has no `netloc` or `scheme` (rejecting absolute URLs to external sites) - Construct a new safe URL from only the validated `path` and `query` components - Use the sanitized URL in `redirect()` instead of the original user input ## Why The original code passed user-controlled input directly to `redirect()`, which could allow an attacker to craft a malicious URL that redirects users to an external site (open redirect attack). By parsing the URL and reconstructing it from only the path and query components, we break the taint chain and ensure only relative URLs are used for redirects. ## Semgrep Finding Details Data from request is passed to redirect(). This is an open redirect and could be exploited. Consider using 'url_for()' to generate links to known locations. If you must use a URL to unknown pages, consider using 'urlparse()' or similar and checking if the 'netloc' property is the same as your site's host name. See the references for more information. @267212124 requested Semgrep Assistant generate this pull request to fix [a finding](https://semgrep.dev/orgs/studentsca023_personal_org/findings/722169005) from the detection rule [python.flask.security.open-redirect.open-redirect](https://semgrep.dev/r/python.flask.security.open-redirect.open-redirect). --- flask_webgoat/auth.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/flask_webgoat/auth.py b/flask_webgoat/auth.py index 6d884ebc..f97b595f 100644 --- a/flask_webgoat/auth.py +++ b/flask_webgoat/auth.py @@ -42,11 +42,16 @@ def login_and_redirect(): 400, ) + parsed = urlparse(url) + if parsed.netloc or parsed.scheme: + return jsonify({"error": "Invalid redirect URL"}), 400 + safe_url = parsed.path + if parsed.query: + safe_url = f"{safe_url}?{parsed.query}" + query = "SELECT id, username, access_level FROM user WHERE username = ? AND password = ?" result = query_db(query, (username, password), True) if result is None: - if not is_safe_url(url): - return jsonify({"error": "Invalid redirect URL"}), 400 - return redirect(url) + return redirect(safe_url) session["user_info"] = (result[0], result[1], result[2]) return jsonify({"success": True})