From d4408f3d5d7fea8f4276531ffd545d8a48c575ff Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 14 May 2026 10:42:12 -0400 Subject: [PATCH] Closes #22198: Restrict ExportTemplate querysets for UI & REST API (#22199) --- netbox/extras/tests/test_views.py | 4 ++-- netbox/netbox/api/viewsets/mixins.py | 5 ++++- netbox/netbox/views/generic/bulk_views.py | 6 +++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/netbox/extras/tests/test_views.py b/netbox/extras/tests/test_views.py index 3d5bd48d1..d20109c2c 100644 --- a/netbox/extras/tests/test_views.py +++ b/netbox/extras/tests/test_views.py @@ -399,7 +399,7 @@ class ExportTemplateExportFlowTest(TestCase): broken_template.object_types.set([site_type]) def test_export_template_invocation(self): - self.add_permissions('dcim.view_site') + self.add_permissions('dcim.view_site', 'extras.view_exporttemplate') url = reverse('dcim:site_list') response = self.client.get(f'{url}?export=Sites Export') @@ -412,7 +412,7 @@ class ExportTemplateExportFlowTest(TestCase): self.assertEqual(rendered_names, {'Site A', 'Site B'}) def test_export_template_render_error_redirects(self): - self.add_permissions('dcim.view_site') + self.add_permissions('dcim.view_site', 'extras.view_exporttemplate') url = reverse('dcim:site_list') # A broken template surfaces an exception during render; the view catches it and redirects diff --git a/netbox/netbox/api/viewsets/mixins.py b/netbox/netbox/api/viewsets/mixins.py index 7f753240e..fd49bd7af 100644 --- a/netbox/netbox/api/viewsets/mixins.py +++ b/netbox/netbox/api/viewsets/mixins.py @@ -41,7 +41,10 @@ class ExportTemplatesMixin: def list(self, request, *args, **kwargs): if 'export' in request.GET: object_type = ObjectType.objects.get_for_model(self.get_serializer_class().Meta.model) - et = ExportTemplate.objects.filter(object_types=object_type, name=request.GET['export']).first() + et = ExportTemplate.objects.restrict(request.user, 'view').filter( + object_types=object_type, + name=request.GET['export'], + ).first() if et is None: raise Http404 queryset = self.filter_queryset(self.get_queryset()) diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 41eeaba88..95da9ce76 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -185,7 +185,11 @@ class ObjectListView(BaseMultiObjectView, ActionsMixin, TableMixin): # Render an ExportTemplate if request.GET['export']: - template = get_object_or_404(ExportTemplate, object_types=object_type, name=request.GET['export']) + template = get_object_or_404( + ExportTemplate.objects.restrict(request.user, 'view'), + object_types=object_type, + name=request.GET['export'], + ) return self.export_template(template, request) # Check for YAML export support on the model