diff --git a/grappelli/views/switch.py b/grappelli/views/switch.py index 8e390b131..db2ee680b 100644 --- a/grappelli/views/switch.py +++ b/grappelli/views/switch.py @@ -8,6 +8,7 @@ from django.http import Http404 from django.shortcuts import redirect from django.utils.html import escape +from django.utils.http import url_has_allowed_host_and_scheme from django.utils.translation import gettext_lazy as _ from grappelli.settings import SWITCH_USER_ORIGINAL, SWITCH_USER_TARGET @@ -28,30 +29,35 @@ def switch_user(request, object_id): # check redirect redirect_url = request.GET.get("redirect", None) - if redirect_url is None or not redirect_url.startswith("/"): + if redirect_url is None or not \ + url_has_allowed_host_and_scheme( + url=redirect_url, + allowed_hosts={request.get_host()}, + require_https=request.is_secure(), + ): raise Http404() - + # check original_user try: original_user = User.objects.get(pk=session_user["id"], is_staff=True) if not SWITCH_USER_ORIGINAL(original_user): messages.add_message(request, messages.ERROR, _("Permission denied.")) - return redirect(request.GET.get("redirect")) + return redirect(redirect_url) except ObjectDoesNotExist: msg = _('%(name)s object with primary key %(key)r does not exist.') % {'name': "User", 'key': escape(session_user["id"])} messages.add_message(request, messages.ERROR, msg) - return redirect(request.GET.get("redirect")) + return redirect(redirect_url) # check new user try: target_user = User.objects.get(pk=object_id, is_staff=True) if target_user != original_user and not SWITCH_USER_TARGET(original_user, target_user): messages.add_message(request, messages.ERROR, _("Permission denied.")) - return redirect(request.GET.get("redirect")) + return redirect(redirect_url) except ObjectDoesNotExist: msg = _('%(name)s object with primary key %(key)r does not exist.') % {'name': "User", 'key': escape(object_id)} messages.add_message(request, messages.ERROR, msg) - return redirect(request.GET.get("redirect")) + return redirect(redirect_url) # find backend if not hasattr(target_user, 'backend'): @@ -66,4 +72,4 @@ def switch_user(request, object_id): if original_user.id != target_user.id: request.session["original_user"] = {"id": original_user.id, "username": original_user.get_username()} - return redirect(request.GET.get("redirect")) + return redirect(redirect_url)