widgets: add check on field_id parameter for select2.json urls (#88250)
gitea/authentic/pipeline/head This commit looks good Details

This commit is contained in:
Yann Weber 2024-03-18 18:25:00 +01:00
parent 634211e1b7
commit 0334e56117
4 changed files with 25 additions and 2 deletions

View File

@ -20,7 +20,7 @@ from functools import reduce
from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.exceptions import BadRequest, PermissionDenied, ValidationError
from django.core.paginator import EmptyPage, Paginator
from django.db import transaction
from django.db.models import BooleanField, Count, ExpressionWrapper, F, Prefetch, Q, Value
@ -772,6 +772,8 @@ class UserOrRoleSelect2View(DetailView):
role = self.get_object()
field_id = self.kwargs.get('field_id', self.request.GET.get('field_id', None))
if not field_id:
raise BadRequest('Invalid ID')
try:
crypto.loads(field_id)
except (crypto.SignatureExpired, crypto.BadSignature):

View File

@ -22,7 +22,7 @@ import pickle
import random
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import PermissionDenied, ValidationError
from django.core.exceptions import BadRequest, PermissionDenied, ValidationError
from django.db import transaction
from django.forms import MediaDefiningClass
from django.http import Http404, HttpResponse
@ -837,10 +837,13 @@ class Select2View(AutoResponseView):
if not self.request.user.is_authenticated or not hasattr(self.request.user, 'filter_by_perm'):
raise Http404('Invalid user')
field_data = self.kwargs.get('field_id', self.request.GET.get('field_id', None))
if not field_data:
raise BadRequest('Invalid ID')
try:
field_data = crypto.loads(field_data)
except (crypto.SignatureExpired, crypto.BadSignature):
raise Http404('Invalid or expired signature.')
widget_class = field_data.get('class')
if not widget_class or not hasattr(widgets, widget_class):
raise Http404('Missing or unknown widget class.')

View File

@ -1476,3 +1476,9 @@ def test_manager_empty_kebab(app, admin, simple_user):
resp = login(app, admin, '/manage/users/')
assert '"extra-actions-menu-opener"' in resp
def test_manager_select2(app, superuser):
login(app, superuser)
response = app.get(reverse('django_select2-json'), expect_errors=True)
assert response.status_code == 400

View File

@ -736,6 +736,18 @@ def test_role_members_user_role_add_remove(app, superuser, settings, simple_role
resp = form.submit().maybe_follow()
def test_role_members_select2(app, superuser, simple_user, settings):
assert superuser.ou is None and simple_user.ou == get_default_ou()
r = Role.objects.create(name='role', slug='role', ou=get_default_ou())
url = reverse('a2-manager-role-members', kwargs={'pk': r.pk})
response = login(app, superuser, url)
select2_url = response.pyquery('select')[0].attrib['data-ajax--url']
select2_response = app.get(select2_url, expect_errors=True)
assert select2_response.status_code == 400
def test_role_table_ordering(app, admin):
Role.objects.create(name='a role')
Role.objects.create(name='bD role')