From e7657a3dd3986b41cf0a0e5968cc603b9d6ae6d8 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Wed, 5 Aug 2026 10:56:46 +0200 Subject: [PATCH] Prevent HTML injection in email preview (Z#23241741) --- src/pretix/base/services/placeholders.py | 14 +++++++++++--- src/pretix/control/views/organizer.py | 16 ++++++---------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/pretix/base/services/placeholders.py b/src/pretix/base/services/placeholders.py index 1776b25e0..4c84b16ef 100644 --- a/src/pretix/base/services/placeholders.py +++ b/src/pretix/base/services/placeholders.py @@ -801,11 +801,10 @@ def get_available_placeholders(event, base_parameters, rich=False): return params -def get_sample_context(event, context_parameters, rich=True): +def prepare_sample_context_for_preview(placeholder_to_sample): context_dict = {} lbl = _('This value will be replaced based on dynamic parameters.') - for k, v in get_available_placeholders(event, context_parameters, rich=rich).items(): - sample = v.render_sample(event) + for k, sample in placeholder_to_sample.items(): if isinstance(sample, PlainHtmlAlternativeString): context_dict[k] = PlainHtmlAlternativeString( '<{el} class="placeholder" title="{title}">{plain}'.format( @@ -830,3 +829,12 @@ def get_sample_context(event, context_parameters, rich=True): escape(sample) )) return context_dict + + +def get_sample_context(event, context_parameters, rich=True): + return prepare_sample_context_for_preview( + { + k: v.render_sample(event) + for k, v in get_available_placeholders(event, context_parameters, rich=rich).items() + } + ) diff --git a/src/pretix/control/views/organizer.py b/src/pretix/control/views/organizer.py index e5de190c0..ca6d5f11f 100644 --- a/src/pretix/control/views/organizer.py +++ b/src/pretix/control/views/organizer.py @@ -108,6 +108,7 @@ from pretix.base.services.export import ( init_organizer_exporters, multiexport, scheduled_organizer_export, ) from pretix.base.services.mail import mail, prefix_subject +from pretix.base.services.placeholders import prepare_sample_context_for_preview from pretix.base.templatetags.rich_text import markdown_compile_email from pretix.base.views.tasks import AsyncAction from pretix.control.forms.exports import ScheduledOrganizerExportForm @@ -345,16 +346,11 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View): # get all supported placeholders with dummy values def placeholders(self, item): - ctx = {} - for p, s in MailSettingsForm(obj=self.request.organizer)._get_sample_context( - MailSettingsForm.base_context[item]).items(): - if s.strip().startswith('*'): - ctx[p] = s - else: - ctx[p] = '{}'.format( - _('This value will be replaced based on dynamic parameters.'), - s - ) + ctx = prepare_sample_context_for_preview( + MailSettingsForm(obj=self.request.organizer)._get_sample_context( + MailSettingsForm.base_context[item] + ) + ) return self.SafeDict(ctx) def post(self, request, *args, **kwargs):