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.contrib import auth
from django import shortcuts
from django import test
from django.test.utils import override_settings
from django.urls import NoReverseMatch
from django.urls import reverse
from keystoneauth1 import exceptions as keystone_exceptions
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,
mock_get_access_token,
next=None):
def mock_redirect_return(param):
if 'bad' not in param:
return original_redirect(param)
else:
raise NoReverseMatch
project = self.data.project_two
projects = [self.data.project_one, self.data.project_two]
user = self.data.user
@@ -1290,24 +1298,26 @@ class OpenStackAuthTests(test.TestCase):
mock_get_access_token.return_value = scoped
mock_project_list.return_value = projects
url = reverse('login')
original_redirect = shortcuts.redirect
with mock.patch('django.shortcuts.redirect',
side_effect=mock_redirect_return):
url = reverse('login')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.post(url, form_data)
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
response = self.client.post(url, form_data)
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL)
url = reverse('switch_tenants', args=[project.id])
url = reverse('switch_tenants', args=[project.id])
scoped._project['id'] = self.data.project_two.id
scoped._project['id'] = self.data.project_two.id
if next:
form_data.update({auth.REDIRECT_FIELD_NAME: next})
if 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
self.assertEqual(response['location'], expected_url)
else:
@@ -1326,6 +1336,9 @@ class OpenStackAuthTests(test.TestCase):
def test_switch_with_next(self):
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(password.PasswordPlugin, 'list_projects')
@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.middleware import csrf
from django import shortcuts
from django.urls import NoReverseMatch
from django.urls import reverse
from django.utils import http
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.') %
{'project_name': request.user.project_name})
messages.success(request, message)
response = shortcuts.redirect(redirect_to)
try:
response = shortcuts.redirect(redirect_to)
except NoReverseMatch:
response = django_http.HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
utils.set_response_cookie(response, 'recent_project',
request.user.project_id)
return response