mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 19:47:20 -06:00
Closes #16700: Audit usage of mark_safe() for consistent escaping
This commit is contained in:
parent
8b62e40874
commit
f4ac23d868
@ -1,6 +1,7 @@
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django_tables2.utils import Accessor
|
from django_tables2.utils import Accessor
|
||||||
|
from django.utils.html import escape
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
from dcim.models import Cable
|
from dcim.models import Cable
|
||||||
@ -35,7 +36,7 @@ class CableTerminationsColumn(tables.Column):
|
|||||||
|
|
||||||
def render(self, value):
|
def render(self, value):
|
||||||
links = [
|
links = [
|
||||||
f'<a href="{term.get_absolute_url()}">{term}</a>' for term in self._get_terminations(value)
|
f'<a href="{term.get_absolute_url()}">{escape(term)}</a>' for term in self._get_terminations(value)
|
||||||
]
|
]
|
||||||
return mark_safe('<br />'.join(links) or '—')
|
return mark_safe('<br />'.join(links) or '—')
|
||||||
|
|
||||||
|
@ -3410,8 +3410,9 @@ class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMix
|
|||||||
if membership_form.is_valid():
|
if membership_form.is_valid():
|
||||||
|
|
||||||
membership_form.save()
|
membership_form.save()
|
||||||
msg = f'Added member <a href="{device.get_absolute_url()}">{escape(device)}</a>'
|
messages.success(request, mark_safe(
|
||||||
messages.success(request, mark_safe(msg))
|
f'Added member <a href="{device.get_absolute_url()}">{escape(device)}</a>'
|
||||||
|
))
|
||||||
|
|
||||||
if '_addanother' in request.POST:
|
if '_addanother' in request.POST:
|
||||||
return redirect(request.get_full_path())
|
return redirect(request.get_full_path())
|
||||||
|
@ -10,6 +10,7 @@ from django.contrib.postgres.fields import ArrayField
|
|||||||
from django.core.validators import RegexValidator, ValidationError
|
from django.core.validators import RegexValidator, ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils.html import escape
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
@ -520,7 +521,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
RegexValidator(
|
RegexValidator(
|
||||||
regex=self.validation_regex,
|
regex=self.validation_regex,
|
||||||
message=mark_safe(_("Values must match this regex: <code>{regex}</code>").format(
|
message=mark_safe(_("Values must match this regex: <code>{regex}</code>").format(
|
||||||
regex=self.validation_regex
|
regex=escape(self.validation_regex)
|
||||||
))
|
))
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from django import template
|
from django import template
|
||||||
|
from django.utils.html import escape
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
from core.models import ObjectType
|
from core.models import ObjectType
|
||||||
@ -59,8 +60,7 @@ def custom_links(context, obj):
|
|||||||
# Add non-grouped links
|
# Add non-grouped links
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
rendered = cl.render(link_context)
|
if rendered := cl.render(link_context):
|
||||||
if rendered:
|
|
||||||
template_code += LINK_BUTTON.format(
|
template_code += LINK_BUTTON.format(
|
||||||
rendered['link'], rendered['link_target'], cl.button_class, rendered['text']
|
rendered['link'], rendered['link_target'], cl.button_class, rendered['text']
|
||||||
)
|
)
|
||||||
@ -75,8 +75,7 @@ def custom_links(context, obj):
|
|||||||
|
|
||||||
for cl in links:
|
for cl in links:
|
||||||
try:
|
try:
|
||||||
rendered = cl.render(link_context)
|
if rendered := cl.render(link_context):
|
||||||
if rendered:
|
|
||||||
links_rendered.append(
|
links_rendered.append(
|
||||||
GROUP_LINK.format(rendered['link'], rendered['link_target'], rendered['text'])
|
GROUP_LINK.format(rendered['link'], rendered['link_target'], rendered['text'])
|
||||||
)
|
)
|
||||||
@ -88,7 +87,7 @@ def custom_links(context, obj):
|
|||||||
|
|
||||||
if links_rendered:
|
if links_rendered:
|
||||||
template_code += GROUP_BUTTON.format(
|
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)
|
return mark_safe(template_code)
|
||||||
|
@ -433,7 +433,7 @@ class LinkedCountColumn(tables.Column):
|
|||||||
f'{k}={getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE}'
|
f'{k}={getattr(record, v) or settings.FILTERS_NULL_CHOICE_VALUE}'
|
||||||
for k, v in self.url_params.items()
|
for k, v in self.url_params.items()
|
||||||
])
|
])
|
||||||
return mark_safe(f'<a href="{url}">{value}</a>')
|
return mark_safe(f'<a href="{url}">{escape(value)}</a>')
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def value(self, value):
|
def value(self, value):
|
||||||
|
@ -39,7 +39,7 @@ def handle_protectederror(obj_list, request, e):
|
|||||||
if hasattr(dependent, 'get_absolute_url'):
|
if hasattr(dependent, 'get_absolute_url'):
|
||||||
dependent_objects.append(f'<a href="{dependent.get_absolute_url()}">{escape(dependent)}</a>')
|
dependent_objects.append(f'<a href="{dependent.get_absolute_url()}">{escape(dependent)}</a>')
|
||||||
else:
|
else:
|
||||||
dependent_objects.append(str(dependent))
|
dependent_objects.append(escape(str(dependent)))
|
||||||
err_message += ', '.join(dependent_objects)
|
err_message += ', '.join(dependent_objects)
|
||||||
|
|
||||||
messages.error(request, mark_safe(err_message))
|
messages.error(request, mark_safe(err_message))
|
||||||
|
@ -58,7 +58,7 @@ def linkify(instance, attr=None):
|
|||||||
url = instance.get_absolute_url()
|
url = instance.get_absolute_url()
|
||||||
return mark_safe(f'<a href="{url}">{escape(text)}</a>')
|
return mark_safe(f'<a href="{url}">{escape(text)}</a>')
|
||||||
except (AttributeError, TypeError):
|
except (AttributeError, TypeError):
|
||||||
return text
|
return escape(text)
|
||||||
|
|
||||||
|
|
||||||
@register.filter()
|
@register.filter()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from django import template
|
from django import template
|
||||||
|
from django.utils.html import escape
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
@ -15,6 +16,6 @@ def nested_tree(obj):
|
|||||||
nodes = obj.get_ancestors(include_self=True)
|
nodes = obj.get_ancestors(include_self=True)
|
||||||
return mark_safe(
|
return mark_safe(
|
||||||
' / '.join(
|
' / '.join(
|
||||||
f'<a href="{node.get_absolute_url()}">{node}</a>' for node in nodes
|
f'<a href="{node.get_absolute_url()}">{escape(node)}</a>' for node in nodes
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user