From bbf4b906e4083dbeadbaa802af5aac18e1896ba3 Mon Sep 17 00:00:00 2001 From: sleepinggenius2 Date: Tue, 26 Jul 2022 17:16:03 -0400 Subject: [PATCH 01/15] Adds patterned_fields support for bulk components --- netbox/dcim/views.py | 1 + netbox/netbox/views/generic/bulk_views.py | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index ec3e9152e..3bec02f5c 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2707,6 +2707,7 @@ class DeviceBulkAddModuleBayView(generic.BulkComponentCreateView): filterset = filtersets.DeviceFilterSet table = tables.DeviceTable default_return_url = 'dcim:device_list' + patterned_fields = ('name', 'label', 'position') class DeviceBulkAddDeviceBayView(generic.BulkComponentCreateView): diff --git a/netbox/netbox/views/generic/bulk_views.py b/netbox/netbox/views/generic/bulk_views.py index 5bdf5cbc9..7e07c57d0 100644 --- a/netbox/netbox/views/generic/bulk_views.py +++ b/netbox/netbox/views/generic/bulk_views.py @@ -795,6 +795,7 @@ class BulkComponentCreateView(GetReturnURLMixin, BaseMultiObjectView): model_form = None filterset = None table = None + patterned_fields = ('name', 'label') def get_required_permission(self): return f'dcim.add_{self.queryset.model._meta.model_name}' @@ -830,16 +831,16 @@ class BulkComponentCreateView(GetReturnURLMixin, BaseMultiObjectView): for obj in data['pk']: - names = data['name_pattern'] - labels = data['label_pattern'] if 'label_pattern' in data else None - for i, name in enumerate(names): - label = labels[i] if labels else None - + pattern_count = len(data[f'{self.patterned_fields[0]}_pattern']) + for i in range(pattern_count): component_data = { - self.parent_field: obj.pk, - 'name': name, - 'label': label + self.parent_field: obj.pk } + + for field_name in self.patterned_fields: + if data.get(f'{field_name}_pattern'): + component_data[field_name] = data[f'{field_name}_pattern'][i] + component_data.update(data) component_form = self.model_form(component_data) if component_form.is_valid(): From c6e25f068d7aeb77f18add68ccab9ced6ff68d9a Mon Sep 17 00:00:00 2001 From: Jason Lavoie Date: Tue, 2 Aug 2022 20:39:56 -0400 Subject: [PATCH 02/15] import/export color field on front- and rear-ports for module-types and device-types Closes: #9906 - Adds `color` field to front and rearport template import forms - Adds `color` field to `to_yaml` export for front and rearport templates --- netbox/dcim/forms/object_import.py | 4 ++-- netbox/dcim/models/device_component_templates.py | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/netbox/dcim/forms/object_import.py b/netbox/dcim/forms/object_import.py index afbcd6543..606333e83 100644 --- a/netbox/dcim/forms/object_import.py +++ b/netbox/dcim/forms/object_import.py @@ -146,7 +146,7 @@ class FrontPortTemplateImportForm(ComponentTemplateImportForm): class Meta: model = FrontPortTemplate fields = [ - 'device_type', 'module_type', 'name', 'type', 'rear_port', 'rear_port_position', 'label', 'description', + 'device_type', 'module_type', 'name', 'type', 'color', 'rear_port', 'rear_port_position', 'label', 'description', ] @@ -158,7 +158,7 @@ class RearPortTemplateImportForm(ComponentTemplateImportForm): class Meta: model = RearPortTemplate fields = [ - 'device_type', 'module_type', 'name', 'type', 'positions', 'label', 'description', + 'device_type', 'module_type', 'name', 'type', 'color', 'positions', 'label', 'description', ] diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index f596cf28b..74252e480 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -462,6 +462,7 @@ class FrontPortTemplate(ModularComponentTemplateModel): return { 'name': self.name, 'type': self.type, + 'color': self.color, 'rear_port': self.rear_port.name, 'rear_port_position': self.rear_port_position, 'label': self.label, @@ -511,6 +512,7 @@ class RearPortTemplate(ModularComponentTemplateModel): return { 'name': self.name, 'type': self.type, + 'color': self.color, 'positions': self.positions, 'label': self.label, 'description': self.description, From a2e84dd279549c7284184ff98da4a1ce23c646c9 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 3 Aug 2022 15:22:51 -0400 Subject: [PATCH 03/15] Changelog for #9827, #9906 --- docs/release-notes/version-3.2.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 5e538890c..1c7eb79e8 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -11,9 +11,11 @@ * [#9881](https://github.com/netbox-community/netbox/issues/9881) - Increase granularity in utilization graph values * [#9882](https://github.com/netbox-community/netbox/issues/9882) - Add manufacturer column to modules table * [#9883](https://github.com/netbox-community/netbox/issues/9883) - Linkify location column in power panels table +* [#9906](https://github.com/netbox-community/netbox/issues/9906) - Include `color` attribute in front & rear port YAML import/export ### Bug Fixes +* [#9827](https://github.com/netbox-community/netbox/issues/9827) - Fix assignment of module bay position during bulk creation * [#9871](https://github.com/netbox-community/netbox/issues/9871) - Fix utilization graph value alignments * [#9884](https://github.com/netbox-community/netbox/issues/9884) - Prevent querying assigned VRF on prefix object init * [#9885](https://github.com/netbox-community/netbox/issues/9885) - Fix child prefix counts when editing/deleting aggregates in bulk From f874e9932d06653e330da65d93c2fe0fd7720968 Mon Sep 17 00:00:00 2001 From: Osamu-kj Date: Thu, 4 Aug 2022 18:52:25 +0200 Subject: [PATCH 04/15] Added HTML Sanitization to the custom fields --- netbox/netbox/tables/columns.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 7da241566..7774a495f 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from glob import escape from typing import Optional import django_tables2 as tables @@ -433,21 +434,21 @@ class CustomFieldColumn(tables.Column): def render(self, value): if self.customfield.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value is True: - return mark_safe('') + return escape('') if self.customfield.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value is False: - return mark_safe('') + return escape('') if self.customfield.type == CustomFieldTypeChoices.TYPE_URL: - return mark_safe(f'{value}') + return escape(f'{value}') if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTISELECT: return ', '.join(v for v in value) if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT: - return mark_safe(', '.join([ + return escape(', '.join([ self._likify_item(obj) for obj in self.customfield.deserialize(value) ])) if value is not None: obj = self.customfield.deserialize(value) - return mark_safe(self._likify_item(obj)) - return self.default + return escape(self._likify_item(obj)) + return escape(self.default) def value(self, value): if isinstance(value, list): From db38ed4f19e5943bf60434f4cfc08d232dbb5e6e Mon Sep 17 00:00:00 2001 From: Osamu-kj Date: Sat, 6 Aug 2022 15:10:31 +0200 Subject: [PATCH 05/15] Fixed the XSS protection code inside custom fields --- netbox/netbox/tables/columns.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 7774a495f..277482512 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -1,5 +1,4 @@ from dataclasses import dataclass -from glob import escape from typing import Optional import django_tables2 as tables @@ -8,6 +7,7 @@ from django.contrib.auth.models import AnonymousUser from django.db.models import DateField, DateTimeField from django.template import Context, Template from django.urls import reverse +from django.utils.html import escape from django.utils.formats import date_format from django.utils.safestring import mark_safe from django_tables2.columns import library @@ -430,25 +430,28 @@ class CustomFieldColumn(tables.Column): def _likify_item(item): if hasattr(item, 'get_absolute_url'): return f'{item}' - return item + return escape(item) def render(self, value): if self.customfield.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value is True: - return escape('') + return mark_safe('') if self.customfield.type == CustomFieldTypeChoices.TYPE_BOOLEAN and value is False: - return escape('') + return mark_safe('') if self.customfield.type == CustomFieldTypeChoices.TYPE_URL: - return escape(f'{value}') + return mark_safe(f'{escape(value)}') if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTISELECT: return ', '.join(v for v in value) if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT: - return escape(', '.join([ + print (mark_safe(', '.join([ + self._likify_item(obj) for obj in self.customfield.deserialize(value) + ]))) + return mark_safe(', '.join([ self._likify_item(obj) for obj in self.customfield.deserialize(value) ])) if value is not None: obj = self.customfield.deserialize(value) - return escape(self._likify_item(obj)) - return escape(self.default) + return mark_safe(self._likify_item(obj)) + return self.default def value(self, value): if isinstance(value, list): From 7141fc8eb03eeba0d751e7af374f7d6a92ea60cb Mon Sep 17 00:00:00 2001 From: Osamu-kj Date: Sat, 6 Aug 2022 17:17:43 +0200 Subject: [PATCH 06/15] Custom fields - removed the debug lines --- netbox/netbox/tables/columns.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 277482512..573ac058c 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -429,7 +429,7 @@ class CustomFieldColumn(tables.Column): @staticmethod def _likify_item(item): if hasattr(item, 'get_absolute_url'): - return f'{item}' + return f'{escape(item)}' return escape(item) def render(self, value): @@ -442,9 +442,6 @@ class CustomFieldColumn(tables.Column): if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTISELECT: return ', '.join(v for v in value) if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT: - print (mark_safe(', '.join([ - self._likify_item(obj) for obj in self.customfield.deserialize(value) - ]))) return mark_safe(', '.join([ self._likify_item(obj) for obj in self.customfield.deserialize(value) ])) From 0e1947bc4bceaf01d519bc7cc2e9fc09768b0409 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 09:58:58 -0400 Subject: [PATCH 07/15] PEP8 fix --- netbox/netbox/tables/columns.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index 573ac058c..e176b9af7 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -7,7 +7,7 @@ from django.contrib.auth.models import AnonymousUser from django.db.models import DateField, DateTimeField from django.template import Context, Template from django.urls import reverse -from django.utils.html import escape +from django.utils.html import escape from django.utils.formats import date_format from django.utils.safestring import mark_safe from django_tables2.columns import library From 135543683db21d2856f5b12311b348e7061ff743 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 10:24:49 -0400 Subject: [PATCH 08/15] Changelog for #9919 --- docs/release-notes/version-3.2.md | 1 + netbox/netbox/tables/columns.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 1c7eb79e8..d13e8db75 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -20,6 +20,7 @@ * [#9884](https://github.com/netbox-community/netbox/issues/9884) - Prevent querying assigned VRF on prefix object init * [#9885](https://github.com/netbox-community/netbox/issues/9885) - Fix child prefix counts when editing/deleting aggregates in bulk * [#9891](https://github.com/netbox-community/netbox/issues/9891) - Ensure consistent ordering for tags during object serialization +* [#9919](https://github.com/netbox-community/netbox/issues/9919) - Fix potential XSS avenue via linked objects in tables --- diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index e176b9af7..f78b9f37c 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -442,9 +442,9 @@ class CustomFieldColumn(tables.Column): if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTISELECT: return ', '.join(v for v in value) if self.customfield.type == CustomFieldTypeChoices.TYPE_MULTIOBJECT: - return mark_safe(', '.join([ + return mark_safe(', '.join( self._likify_item(obj) for obj in self.customfield.deserialize(value) - ])) + )) if value is not None: obj = self.customfield.deserialize(value) return mark_safe(self._likify_item(obj)) From 90317adae77c7aeab79d798c1e6f3a983d18fd8a Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 10:47:07 -0400 Subject: [PATCH 09/15] Clean up usages of mark_safe() --- netbox/dcim/views.py | 5 ++--- netbox/netbox/views/generic/object_views.py | 6 +++--- netbox/utilities/templatetags/builtins/filters.py | 4 ++-- netbox/utilities/templatetags/helpers.py | 4 +--- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 3bec02f5c..0bdca686d 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3083,7 +3083,7 @@ class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMix if membership_form.is_valid(): membership_form.save() - msg = 'Added member {}'.format(device.get_absolute_url(), escape(device)) + msg = f'Added member {escape(device)}' messages.success(request, mark_safe(msg)) if '_addanother' in request.POST: @@ -3128,8 +3128,7 @@ class VirtualChassisRemoveMemberView(ObjectPermissionRequiredMixin, GetReturnURL # Protect master device from being removed virtual_chassis = VirtualChassis.objects.filter(master=device).first() if virtual_chassis is not None: - msg = 'Unable to remove master device {} from the virtual chassis.'.format(escape(device)) - messages.error(request, mark_safe(msg)) + messages.error(request, f'Unable to remove master device {device} from the virtual chassis.') return redirect(device.get_absolute_url()) if form.is_valid(): diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py index 4ebfe71cc..88e078ae3 100644 --- a/netbox/netbox/views/generic/object_views.py +++ b/netbox/netbox/views/generic/object_views.py @@ -386,10 +386,10 @@ class ObjectEditView(GetReturnURLMixin, BaseObjectView): ) logger.info(f"{msg} {obj} (PK: {obj.pk})") if hasattr(obj, 'get_absolute_url'): - msg = '{} {}'.format(msg, obj.get_absolute_url(), escape(obj)) + msg = mark_safe(f'{msg} {escape(obj)}') else: - msg = '{} {}'.format(msg, escape(obj)) - messages.success(request, mark_safe(msg)) + msg = f'{msg} {obj}' + messages.success(request, msg) if '_addanother' in request.POST: redirect_url = request.path diff --git a/netbox/utilities/templatetags/builtins/filters.py b/netbox/utilities/templatetags/builtins/filters.py index 5a6841286..bc395e438 100644 --- a/netbox/utilities/templatetags/builtins/filters.py +++ b/netbox/utilities/templatetags/builtins/filters.py @@ -86,8 +86,8 @@ def placeholder(value): """ if value not in ('', None): return value - placeholder = '' - return mark_safe(placeholder) + + return mark_safe('') @register.filter() diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index db4d14c24..67ed553b2 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -109,9 +109,7 @@ def annotated_date(date_value): long_ts = date(date_value, 'DATETIME_FORMAT') short_ts = date(date_value, 'SHORT_DATETIME_FORMAT') - span = f'{short_ts}' - - return mark_safe(span) + return mark_safe(f'{short_ts}') @register.simple_tag From 36ac83a319f1dbd1df3752c9ab8f129eefb23f9b Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 11:43:27 -0400 Subject: [PATCH 10/15] Fixes #9949: Fix KeyError exception resulting from invalid API token provisioning request --- docs/release-notes/version-3.2.md | 1 + netbox/users/api/views.py | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index d13e8db75..0ee235a82 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -21,6 +21,7 @@ * [#9885](https://github.com/netbox-community/netbox/issues/9885) - Fix child prefix counts when editing/deleting aggregates in bulk * [#9891](https://github.com/netbox-community/netbox/issues/9891) - Ensure consistent ordering for tags during object serialization * [#9919](https://github.com/netbox-community/netbox/issues/9919) - Fix potential XSS avenue via linked objects in tables +* [#9949](https://github.com/netbox-community/netbox/issues/9949) - Fix KeyError exception resulting from invalid API token provisioning request --- diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index c3495afdf..e5c2bc8ab 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -74,11 +74,11 @@ class TokenProvisionView(APIView): serializer.is_valid() # Authenticate the user account based on the provided credentials - user = authenticate( - request=request, - username=serializer.data['username'], - password=serializer.data['password'] - ) + username = serializer.data.get('username') + password = serializer.data.get('password') + if not username or not password: + raise AuthenticationFailed("Username and password must be provided to provision a token.") + user = authenticate(request=request, username=username, password=password) if user is None: raise AuthenticationFailed("Invalid username/password") From 876251c1cf6da80894780d3856412a2918da9d0e Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 11:48:43 -0400 Subject: [PATCH 11/15] Fixes #9948: Fix TypeError exception when requesting API tokens list as non-authenticated user --- docs/release-notes/version-3.2.md | 1 + netbox/users/api/views.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 0ee235a82..745ace110 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -21,6 +21,7 @@ * [#9885](https://github.com/netbox-community/netbox/issues/9885) - Fix child prefix counts when editing/deleting aggregates in bulk * [#9891](https://github.com/netbox-community/netbox/issues/9891) - Ensure consistent ordering for tags during object serialization * [#9919](https://github.com/netbox-community/netbox/issues/9919) - Fix potential XSS avenue via linked objects in tables +* [#9948](https://github.com/netbox-community/netbox/issues/9948) - Fix TypeError exception when requesting API tokens list as non-authenticated user * [#9949](https://github.com/netbox-community/netbox/issues/9949) - Fix KeyError exception resulting from invalid API token provisioning request --- diff --git a/netbox/users/api/views.py b/netbox/users/api/views.py index e5c2bc8ab..66ef92ab7 100644 --- a/netbox/users/api/views.py +++ b/netbox/users/api/views.py @@ -58,6 +58,8 @@ class TokenViewSet(NetBoxModelViewSet): # Workaround for schema generation (drf_yasg) if getattr(self, 'swagger_fake_view', False): return queryset.none() + if not self.request.user.is_authenticated: + return queryset.none() if self.request.user.is_superuser: return queryset return queryset.filter(user=self.request.user) From 8721ad987cf178cc5421f64c28b1772bdabaa967 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 12:22:22 -0400 Subject: [PATCH 12/15] Fixes #9952: Prevent InvalidMove when attempting to assign a nested child object as parent --- docs/release-notes/version-3.2.md | 1 + netbox/netbox/models/__init__.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 745ace110..f231b6e58 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -23,6 +23,7 @@ * [#9919](https://github.com/netbox-community/netbox/issues/9919) - Fix potential XSS avenue via linked objects in tables * [#9948](https://github.com/netbox-community/netbox/issues/9948) - Fix TypeError exception when requesting API tokens list as non-authenticated user * [#9949](https://github.com/netbox-community/netbox/issues/9949) - Fix KeyError exception resulting from invalid API token provisioning request +* [#9952](https://github.com/netbox-community/netbox/issues/9952) - Prevent InvalidMove when attempting to assign a nested child object as parent --- diff --git a/netbox/netbox/models/__init__.py b/netbox/netbox/models/__init__.py index b3bfe06c0..ea2feb8de 100644 --- a/netbox/netbox/models/__init__.py +++ b/netbox/netbox/models/__init__.py @@ -89,9 +89,9 @@ class NestedGroupModel(NetBoxFeatureSet, MPTTModel): super().clean() # An MPTT model cannot be its own parent - if self.pk and self.parent_id == self.pk: + if self.pk and self.parent and self.parent in self.get_descendants(include_self=True): raise ValidationError({ - "parent": "Cannot assign self as parent." + "parent": f"Cannot assign self or child {self._meta.verbose_name} as parent." }) From caca074161977fcbd7d3d0cd0e02b42efb3e8184 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 14:21:42 -0400 Subject: [PATCH 13/15] Fixes #9950: Prevent redirection to arbitrary URLs via 'next' parameter on login URL --- docs/release-notes/version-3.2.md | 1 + netbox/users/views.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index f231b6e58..46718837e 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -23,6 +23,7 @@ * [#9919](https://github.com/netbox-community/netbox/issues/9919) - Fix potential XSS avenue via linked objects in tables * [#9948](https://github.com/netbox-community/netbox/issues/9948) - Fix TypeError exception when requesting API tokens list as non-authenticated user * [#9949](https://github.com/netbox-community/netbox/issues/9949) - Fix KeyError exception resulting from invalid API token provisioning request +* [#9950](https://github.com/netbox-community/netbox/issues/9950) - Prevent redirection to arbitrary URLs via `next` parameter on login URL * [#9952](https://github.com/netbox-community/netbox/issues/9952) - Prevent InvalidMove when attempting to assign a nested child object as parent --- diff --git a/netbox/users/views.py b/netbox/users/views.py index 344f375fc..f08cac844 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -10,6 +10,7 @@ from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.decorators import method_decorator +from django.utils.http import url_has_allowed_host_and_scheme from django.views.decorators.debug import sensitive_post_parameters from django.views.generic import View from social_core.backends.utils import load_backends @@ -91,7 +92,7 @@ class LoginView(View): data = request.POST if request.method == "POST" else request.GET redirect_url = data.get('next', settings.LOGIN_REDIRECT_URL) - if redirect_url and redirect_url.startswith('/'): + if redirect_url and url_has_allowed_host_and_scheme(redirect_url, allowed_hosts=None): logger.debug(f"Redirecting user to {redirect_url}") else: if redirect_url: From ce7fb8ab17406a8eba02055c22ec0b6cbe8ef425 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 15:17:36 -0400 Subject: [PATCH 14/15] Release v3.2.8 --- .github/ISSUE_TEMPLATE/bug_report.yaml | 2 +- .github/ISSUE_TEMPLATE/feature_request.yaml | 2 +- base_requirements.txt | 2 +- docs/release-notes/version-3.2.md | 2 +- netbox/netbox/settings.py | 2 +- requirements.txt | 12 ++++++------ 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 332a0ad75..c26584f32 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.2.7 + placeholder: v3.2.8 validations: required: true - type: dropdown diff --git a/.github/ISSUE_TEMPLATE/feature_request.yaml b/.github/ISSUE_TEMPLATE/feature_request.yaml index ff9b5e358..e6be95e49 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yaml +++ b/.github/ISSUE_TEMPLATE/feature_request.yaml @@ -14,7 +14,7 @@ body: attributes: label: NetBox version description: What version of NetBox are you currently running? - placeholder: v3.2.7 + placeholder: v3.2.8 validations: required: true - type: dropdown diff --git a/base_requirements.txt b/base_requirements.txt index 9dc85231b..672ce402c 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -4,7 +4,7 @@ bleach # The Python web framework on which NetBox is built # https://github.com/django/django -Django +Django<4.1 # Django middleware which permits cross-domain API requests # https://github.com/OttoYiu/django-cors-headers diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index 46718837e..bf6f2f848 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,6 +1,6 @@ # NetBox v3.2 -## v3.2.8 (FUTURE) +## v3.2.8 (2022-08-08) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index c7e49c1be..12ab44399 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -29,7 +29,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.8-dev' +VERSION = '3.2.8' # Hostname HOSTNAME = platform.node() diff --git a/requirements.txt b/requirements.txt index f987ad7ba..59bd1e8cd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ bleach==5.0.1 -Django==4.0.6 +Django==4.0.7 django-cors-headers==3.13.0 django-debug-toolbar==3.5.0 django-filter==22.1 @@ -13,22 +13,22 @@ django-tables2==2.4.1 django-taggit==2.1.0 django-timezone-field==5.0 djangorestframework==3.13.1 -drf-yasg[validation]==1.20.0 +drf-yasg[validation]==1.21.3 graphene-django==2.15.0 gunicorn==20.1.0 Jinja2==3.1.2 -Markdown==3.3.7 -markdown-include==0.6.0 +Markdown==3.4.1 +markdown-include==0.7.0 mkdocs-material==8.3.9 mkdocstrings[python-legacy]==0.19.0 netaddr==0.8.0 Pillow==9.2.0 psycopg2-binary==2.9.3 PyYAML==6.0 -sentry-sdk==1.7.0 +sentry-sdk==1.9.2 social-auth-app-django==5.0.0 social-auth-core==4.3.0 -svgwrite==1.4.2 +svgwrite==1.4.3 tablib==3.2.1 tzdata==2022.1 From 064d7f3bd0a803ed55198455e54a29c8f7c0adc2 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Mon, 8 Aug 2022 15:34:13 -0400 Subject: [PATCH 15/15] PRVB --- docs/release-notes/version-3.2.md | 4 ++++ netbox/netbox/settings.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/version-3.2.md b/docs/release-notes/version-3.2.md index bf6f2f848..56a35cc02 100644 --- a/docs/release-notes/version-3.2.md +++ b/docs/release-notes/version-3.2.md @@ -1,5 +1,9 @@ # NetBox v3.2 +## v3.2.9 (FUTURE) + +--- + ## v3.2.8 (2022-08-08) ### Enhancements diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 12ab44399..d38289d43 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -29,7 +29,7 @@ django.utils.encoding.force_text = force_str # Environment setup # -VERSION = '3.2.8' +VERSION = '3.2.9-dev' # Hostname HOSTNAME = platform.node()