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 (
26+ test_url .scheme in ("http" , "https" )
27+ and ref_url .netloc == test_url .netloc
28+ )
29+
30+
31+ def _safe_redirect ():
32+ target = flask .request .args .get ("next" )
33+ if not is_safe_url (target ):
34+ target = "/manager"
35+ return flask .redirect (target )
1936
2037
2138def init_sso (app ):
@@ -36,9 +53,7 @@ def init_sso(app):
3653 @app .route ("/login" )
3754 def login ():
3855 if "openid" in flask .session :
39- return flask .redirect (
40- _safe_redirect_url (flask .request .args .get ("next" ))
41- )
56+ return _safe_redirect ()
4257
4358 redirect_uri = flask .url_for ("oauth_callback" , _external = True )
4459 return oauth .canonical .authorize_redirect (redirect_uri )
@@ -77,10 +92,7 @@ def oauth_callback():
7792 "email" : token ["userinfo" ]["email" ],
7893 "fullname" : token ["userinfo" ]["name" ],
7994 }
80-
81- return flask .redirect (
82- _safe_redirect_url (flask .request .args .get ("next" ))
83- )
95+ return _safe_redirect ()
8496
8597
8698def login_required (func ):
0 commit comments