11import functools
22import os
3- from urllib .parse import urlparse
3+ from urllib .parse import urljoin , urlparse
44
55import flask
66from authlib .integrations .flask_client import OAuth
1212LAUNCHPAD_API_URL = "https://api.launchpad.net/1.0"
1313
1414
15- def _safe_redirect_url (target ):
16- if target and urlparse (target ).netloc == "" :
17- return target
18- return "/manager"
15+ def is_safe_url (target ):
16+ # Ensure the target is not empty
17+ if not target :
18+ return False
19+
20+ # Get the root URL of your own application
21+ ref_url = urlparse (flask .request .host_url )
22+ test_url = urlparse (urljoin (flask .request .host_url , target ))
23+
24+ # Check that the scheme is http/https and the netloc matches your host
25+ return test_url .scheme in ('http' , 'https' ) and \
26+ ref_url .netloc == test_url .netloc
27+
28+
29+ def _safe_redirect ():
30+ target = flask .request .args .get ('next' )
31+ if not is_safe_url (target ):
32+ target = "/manager"
33+ return flask .redirect (target )
1934
2035
2136def init_sso (app ):
@@ -36,9 +51,7 @@ def init_sso(app):
3651 @app .route ("/login" )
3752 def login ():
3853 if "openid" in flask .session :
39- return flask .redirect (
40- _safe_redirect_url (flask .request .args .get ("next" ))
41- )
54+ return _safe_redirect ()
4255
4356 redirect_uri = flask .url_for ("oauth_callback" , _external = True )
4457 return oauth .canonical .authorize_redirect (redirect_uri )
@@ -77,10 +90,7 @@ def oauth_callback():
7790 "email" : token ["userinfo" ]["email" ],
7891 "fullname" : token ["userinfo" ]["name" ],
7992 }
80-
81- return flask .redirect (
82- _safe_redirect_url (flask .request .args .get ("next" ))
83- )
93+ return _safe_redirect ()
8494
8595
8696def login_required (func ):
0 commit comments