From 6fdd82992c8b2151b662db83a909f67270096ba8 Mon Sep 17 00:00:00 2001 From: adilburaksen Date: Sat, 16 May 2026 21:24:27 +0300 Subject: [PATCH] handlers: reject protocol-relative URLs in redirect validation _SAFE_URL_PATTERN's relative-URL branch matched the empty string prefix of '//evil.com', so check_redirect_url accepted protocol-relative URLs as safe. Browsers interpret '//evil.com/path' as 'same-scheme://evil.com/path', enabling open redirect from any endpoint that passes the user-supplied 'next' / 'redirect' parameter through check_redirect_url. Add a negative lookahead (?!//) before the relative-URL branch so that any URL beginning with '//' is rejected unless it already matched the explicit-scheme branch (http://, https://, etc). --- src/appengine/handlers/base_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/appengine/handlers/base_handler.py b/src/appengine/handlers/base_handler.py index dc69a51e5aa..d054ee08034 100644 --- a/src/appengine/handlers/base_handler.py +++ b/src/appengine/handlers/base_handler.py @@ -45,7 +45,7 @@ # https://github.com/google/closure-library/blob/ # 3037e09cc471bfe99cb8f0ee22d9366583a20c28/closure/goog/html/safeurl.js _SAFE_URL_PATTERN = re.compile( - r'^(?:(?:https?|mailto|ftp):|[^:/?#]*(?:[/?#]|$))', flags=re.IGNORECASE) + r'^(?:(?:https?|mailto|ftp):|(?!//)[^:/?#]*(?:[/?#]|$))', flags=re.IGNORECASE) def add_jinja2_filter(name, fn):