|
7 | 7 | from django.contrib.auth import logout as auth_logout |
8 | 8 | from django.contrib.auth import authenticate, login |
9 | 9 | from django.http import HttpResponseRedirect |
| 10 | +from django.utils.http import url_has_allowed_host_and_scheme |
10 | 11 | from django.shortcuts import redirect |
11 | 12 | from urllib.parse import parse_qs, urlencode |
12 | 13 |
|
@@ -76,7 +77,11 @@ def openid(request): |
76 | 77 | logger.debug("OIDC client is None, attempting to initialize") |
77 | 78 | _initialize_client() |
78 | 79 | request.session["acr_value"] = CLIENT.get_default_acr_value() |
79 | | - request.session["next"] = request.GET.get("next", "/") |
| 80 | + if url_has_allowed_host_and_scheme(request.GET.get("next", "/"), None): |
| 81 | + request.session["next"] = request.GET.get("next", "/") |
| 82 | + else: |
| 83 | + logger.warning(f"Invalid redirect: {request.GET.get("next")}") |
| 84 | + request.session["next"] = "/" |
80 | 85 | # Create the authentication request |
81 | 86 | return CLIENT.create_authn_request(request.session) |
82 | 87 | except Exception as err: |
@@ -135,7 +140,11 @@ def login_callback(request): |
135 | 140 | # In the event of a state mismatch between OP and session, redirect the user to the |
136 | 141 | # beginning of login process without raising an error to the user. Attempt once. |
137 | 142 | logger.warning(f"No State Defined: {nsd_err}") |
138 | | - return redirect(request.session.get("next", "/")) |
| 143 | + if url_has_allowed_host_and_scheme(request.GET.get("next", "/"), None): |
| 144 | + return redirect(request.session.get("next", "/")) |
| 145 | + else: |
| 146 | + logger.warning(f"Invalid redirect: {request.GET.get("next")}") |
| 147 | + return redirect("/") |
139 | 148 | else: |
140 | 149 | # Clear the flag if the exception is not caught |
141 | 150 | request.session.pop("redirect_attempted", None) |
|
0 commit comments