From da6d194420344956f2ed32f359773d6fe87cbac6 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 2 Apr 2026 10:02:21 -0400 Subject: [PATCH] fix!: Merge commit from fork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cherry-pick from https://github.com/openedx/openedx-platform/pull/38274 The view_survey endpoint accepted a redirect_url GET parameter and passed it directly to HttpResponseRedirect() with no validation. If a non-existent survey name was requested, this produced an immediate 302 to an attacker-controlled URL. If a valid survey was requested, the same URL was embedded in a hidden _redirect_url form field; after submission, submit_answers echoed it back in JSON and client-side JS used it as location.href — a second unvalidated redirect path. Fix both by ignoring user-supplied redirect URLs entirely: - view_survey no longer reads redirect_url from GET params - submit_answers always redirects to reverse('dashboard') rather than reading _redirect_url from the POST body Note: view_student_survey retains its redirect_url parameter because it is also called from the courseware view (courseware/views/views.py), which passes a server-controlled course_home_url. That call path is unaffected. Fixes: https://github.com/openedx/openedx-platform/security/advisories/GHSA-2843-x998-f8r2 BREAKING CHANGE: The redirect_url GET parameter on /survey// is no longer honored. Requests that previously redirected to a caller-specified URL after survey completion will now always redirect to the dashboard. --- lms/djangoapps/survey/views.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lms/djangoapps/survey/views.py b/lms/djangoapps/survey/views.py index c6a3b5697942..328b32f9e7da 100644 --- a/lms/djangoapps/survey/views.py +++ b/lms/djangoapps/survey/views.py @@ -26,9 +26,7 @@ def view_survey(request, survey_name): """ View to render the survey to the end user """ - redirect_url = request.GET.get('redirect_url') - - return view_student_survey(request.user, survey_name, redirect_url=redirect_url) + return view_student_survey(request.user, survey_name) def view_student_survey(user, survey_name, course=None, redirect_url=None, is_required=False, skip_redirect_url=None): @@ -88,9 +86,7 @@ def submit_answers(request, survey_name): array_val = request.POST.getlist(key) answers[key] = request.POST[key] if len(array_val) == 0 else ','.join(array_val) - # the URL we are supposed to redirect to is - # in a hidden form field - redirect_url = answers['_redirect_url'] if '_redirect_url' in answers else reverse('dashboard') + redirect_url = reverse('dashboard') course_key = CourseKey.from_string(answers['course_id']) if 'course_id' in answers else None