66
77import logging
88import warnings
9+ import re
910from urllib .parse import urlparse
1011
1112from authlib .integrations .base_client .errors import OAuthError
3435auth_routes = Blueprint ("oidc_auth" , __name__ )
3536
3637
38+ def validate_return_url (next , url_root ):
39+ if next == url_root :
40+ return next
41+ if not re .match (r"^[a-zA-Z0-9:\/.\-@%?!&+#_=*~']{2,256}$" , next ):
42+ logger .debug ("The redirect url you provided contains invalid characters" )
43+ return url_root
44+
45+ temp_url = next
46+ if not next .startswith (('http://' , 'https://' )):
47+ # add a scheme for urlparse
48+ temp_url = 'http://' + next
49+
50+ parsed_url = urlparse (temp_url )
51+ parsed_root = urlparse (url_root )
52+ if not parsed_url .netloc and parsed_url .path .startswith ('/' ):
53+ # this is a valid relative url
54+ return next
55+ if parsed_url .netloc == parsed_root .netloc :
56+ # netloc should match for valid absolute urls
57+ return next
58+ logger .debug ("The redirect url you provided is invalid" )
59+ return url_root
60+
61+
3762@auth_routes .route ("/login" , endpoint = "login" )
3863def login_view ():
3964 if current_app .config ["OIDC_OVERWRITE_REDIRECT_URI" ]:
@@ -44,7 +69,8 @@ def login_view():
4469 )
4570 else :
4671 redirect_uri = url_for ("oidc_auth.authorize" , _external = True )
47- session ["next" ] = request .args .get ("next" , request .url_root )
72+ next = request .args .get ("next" , request .url_root )
73+ session ["next" ] = validate_return_url (next , request .url_root )
4874 before_login_redirect .send (
4975 g ._oidc_auth ,
5076 redirect_uri = redirect_uri ,
@@ -99,7 +125,8 @@ def logout_view():
99125 flash ("Your session expired, please reconnect." )
100126 else :
101127 flash ("You were successfully logged out." )
102- return_to = request .args .get ("next" , request .url_root )
128+ next = request .args .get ("next" , request .url_root )
129+ return_to = validate_return_url (next , request .url_root )
103130 after_logout .send (g ._oidc_auth , reason = reason , return_to = return_to )
104131 return redirect (return_to )
105132
0 commit comments