diff --git a/netbox/dcim/tables/cables.py b/netbox/dcim/tables/cables.py index 0fb2f7d61..e4c16f142 100644 --- a/netbox/dcim/tables/cables.py +++ b/netbox/dcim/tables/cables.py @@ -1,6 +1,7 @@ from django.utils.translation import gettext_lazy as _ import django_tables2 as tables from django_tables2.utils import Accessor +from django.utils.html import escape from django.utils.safestring import mark_safe from dcim.models import Cable @@ -35,7 +36,7 @@ class CableTerminationsColumn(tables.Column): def render(self, value): links = [ - f'{term}' for term in self._get_terminations(value) + f'{escape(term)}' for term in self._get_terminations(value) ] return mark_safe('
'.join(links) or '—') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 3b8c862a7..87f351e4d 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -3410,8 +3410,9 @@ class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMix if membership_form.is_valid(): membership_form.save() - msg = f'Added member {escape(device)}' - messages.success(request, mark_safe(msg)) + messages.success(request, mark_safe( + f'Added member {escape(device)}' + )) if '_addanother' in request.POST: return redirect(request.get_full_path()) diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 240998146..d2397fee8 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -10,6 +10,7 @@ from django.contrib.postgres.fields import ArrayField from django.core.validators import RegexValidator, ValidationError from django.db import models from django.urls import reverse +from django.utils.html import escape from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy as _ @@ -520,7 +521,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): RegexValidator( regex=self.validation_regex, message=mark_safe(_("Values must match this regex: {regex}").format( - regex=self.validation_regex + regex=escape(self.validation_regex) )) ) ] diff --git a/netbox/extras/templatetags/custom_links.py b/netbox/extras/templatetags/custom_links.py index 849955cd4..dd28a8160 100644 --- a/netbox/extras/templatetags/custom_links.py +++ b/netbox/extras/templatetags/custom_links.py @@ -1,4 +1,5 @@ from django import template +from django.utils.html import escape from django.utils.safestring import mark_safe from core.models import ObjectType @@ -59,8 +60,7 @@ def custom_links(context, obj): # Add non-grouped links else: try: - rendered = cl.render(link_context) - if rendered: + if rendered := cl.render(link_context): template_code += LINK_BUTTON.format( rendered['link'], rendered['link_target'], cl.button_class, rendered['text'] ) @@ -75,8 +75,7 @@ def custom_links(context, obj): for cl in links: try: - rendered = cl.render(link_context) - if rendered: + if rendered := cl.render(link_context): links_rendered.append( GROUP_LINK.format(rendered['link'], rendered['link_target'], rendered['text']) ) @@ -88,7 +87,7 @@ def custom_links(context, obj): if links_rendered: template_code += GROUP_BUTTON.format( - links[0].button_class, group, ''.join(links_rendered) + links[0].button_class, escape(group), ''.join(links_rendered) ) return mark_safe(template_code) diff --git a/netbox/netbox/tables/columns.py b/netbox/netbox/tables/columns.py index cfe6c9be6..2576f70e5 100644 --- a/netbox/netbox/tables/columns.py +++ b/netbox/netbox/tables/columns.py @@ -433,7 +433,7 @@ class LinkedCountColumn(tables.Column): f'{k}={getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE}' for k, v in self.url_params.items() ]) - return mark_safe(f'{value}') + return mark_safe(f'{escape(value)}') return value def value(self, value): diff --git a/netbox/utilities/error_handlers.py b/netbox/utilities/error_handlers.py index 89e3a967d..386ec6f39 100644 --- a/netbox/utilities/error_handlers.py +++ b/netbox/utilities/error_handlers.py @@ -39,7 +39,7 @@ def handle_protectederror(obj_list, request, e): if hasattr(dependent, 'get_absolute_url'): dependent_objects.append(f'{escape(dependent)}') else: - dependent_objects.append(str(dependent)) + dependent_objects.append(escape(str(dependent))) err_message += ', '.join(dependent_objects) messages.error(request, mark_safe(err_message)) diff --git a/netbox/utilities/templatetags/builtins/filters.py b/netbox/utilities/templatetags/builtins/filters.py index 77db007cc..738b9a23e 100644 --- a/netbox/utilities/templatetags/builtins/filters.py +++ b/netbox/utilities/templatetags/builtins/filters.py @@ -58,7 +58,7 @@ def linkify(instance, attr=None): url = instance.get_absolute_url() return mark_safe(f'{escape(text)}') except (AttributeError, TypeError): - return text + return escape(text) @register.filter() diff --git a/netbox/utilities/templatetags/mptt.py b/netbox/utilities/templatetags/mptt.py index 783c2654f..96326e9a2 100644 --- a/netbox/utilities/templatetags/mptt.py +++ b/netbox/utilities/templatetags/mptt.py @@ -1,4 +1,5 @@ from django import template +from django.utils.html import escape from django.utils.safestring import mark_safe register = template.Library() @@ -15,6 +16,6 @@ def nested_tree(obj): nodes = obj.get_ancestors(include_self=True) return mark_safe( ' / '.join( - f'{node}' for node in nodes + f'{escape(node)}' for node in nodes ) )