Enable redirect URL check

Redirect parameter at project change button link was not validated. In
case of invalid parameter, user get response 500

Partial-Bug: #1961595
Change-Id: I7cebf4fa8d09a061774dfaba6b230d8090b7ac73
This commit is contained in:
Vadym Markov
2022-02-21 16:46:38 +02:00
parent a95d703c98
commit 9115b4a2de
2 changed files with 30 additions and 13 deletions

View File

@@ -16,8 +16,10 @@ import uuid
from django.conf import settings from django.conf import settings
from django.contrib import auth from django.contrib import auth
from django import shortcuts
from django import test from django import test
from django.test.utils import override_settings from django.test.utils import override_settings
from django.urls import NoReverseMatch
from django.urls import reverse from django.urls import reverse
from keystoneauth1 import exceptions as keystone_exceptions from keystoneauth1 import exceptions as keystone_exceptions
from keystoneauth1.identity import v3 as v3_auth from keystoneauth1.identity import v3 as v3_auth
@@ -1279,6 +1281,12 @@ class OpenStackAuthTests(test.TestCase):
def test_switch(self, mock_get_access, mock_project_list, def test_switch(self, mock_get_access, mock_project_list,
mock_get_access_token, mock_get_access_token,
next=None): next=None):
def mock_redirect_return(param):
if 'bad' not in param:
return original_redirect(param)
else:
raise NoReverseMatch
project = self.data.project_two project = self.data.project_two
projects = [self.data.project_one, self.data.project_two] projects = [self.data.project_one, self.data.project_two]
user = self.data.user user = self.data.user
@@ -1290,6 +1298,9 @@ class OpenStackAuthTests(test.TestCase):
mock_get_access_token.return_value = scoped mock_get_access_token.return_value = scoped
mock_project_list.return_value = projects mock_project_list.return_value = projects
original_redirect = shortcuts.redirect
with mock.patch('django.shortcuts.redirect',
side_effect=mock_redirect_return):
url = reverse('login') url = reverse('login')
response = self.client.get(url) response = self.client.get(url)
@@ -1304,10 +1315,9 @@ class OpenStackAuthTests(test.TestCase):
if next: if next:
form_data.update({auth.REDIRECT_FIELD_NAME: next}) form_data.update({auth.REDIRECT_FIELD_NAME: next})
response = self.client.get(url, form_data) response = self.client.get(url, form_data)
if next: if next and 'bad' not in next:
expected_url = next expected_url = next
self.assertEqual(response['location'], expected_url) self.assertEqual(response['location'], expected_url)
else: else:
@@ -1326,6 +1336,9 @@ class OpenStackAuthTests(test.TestCase):
def test_switch_with_next(self): def test_switch_with_next(self):
self.test_switch(next='/next_url') self.test_switch(next='/next_url')
def test_switch_with_wrong_next(self):
self.test_switch(next='/bad_url')
@mock.patch.object(v3_auth.Token, 'get_access') @mock.patch.object(v3_auth.Token, 'get_access')
@mock.patch.object(password.PasswordPlugin, 'list_projects') @mock.patch.object(password.PasswordPlugin, 'list_projects')
@mock.patch.object(v3_auth.Password, 'get_access') @mock.patch.object(v3_auth.Password, 'get_access')

View File

@@ -22,6 +22,7 @@ from django.contrib import messages
from django import http as django_http from django import http as django_http
from django.middleware import csrf from django.middleware import csrf
from django import shortcuts from django import shortcuts
from django.urls import NoReverseMatch
from django.urls import reverse from django.urls import reverse
from django.utils import http from django.utils import http
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@@ -317,7 +318,10 @@ def switch(request, tenant_id, redirect_field_name=auth.REDIRECT_FIELD_NAME):
_('Switch to project "%(project_name)s" successful.') % _('Switch to project "%(project_name)s" successful.') %
{'project_name': request.user.project_name}) {'project_name': request.user.project_name})
messages.success(request, message) messages.success(request, message)
try:
response = shortcuts.redirect(redirect_to) response = shortcuts.redirect(redirect_to)
except NoReverseMatch:
response = django_http.HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
utils.set_response_cookie(response, 'recent_project', utils.set_response_cookie(response, 'recent_project',
request.user.project_id) request.user.project_id)
return response return response