From f874e9932d06653e330da65d93c2fe0fd7720968 Mon Sep 17 00:00:00 2001 From: Osamu-kj Date: Thu, 4 Aug 2022 18:52:25 +0200 Subject: [PATCH 1/4] 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 2/4] 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 3/4] 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 4/4] 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