From ea819530f9f040e15b1bed20050780a3d7b14f3a Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Mon, 20 Jul 2026 13:15:09 +0200 Subject: [PATCH] Escape HTML arguments to translation strings (#6399) --- src/pretix/base/context.py | 21 ++++++++++++--------- src/pretix/plugins/paypal/payment.py | 6 ++++-- src/pretix/plugins/paypal2/payment.py | 4 +++- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/pretix/base/context.py b/src/pretix/base/context.py index 475dfd4f1..d7948083f 100644 --- a/src/pretix/base/context.py +++ b/src/pretix/base/context.py @@ -23,6 +23,7 @@ import sys from django.conf import settings from django.urls import reverse +from django.utils.html import escape, format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext @@ -35,21 +36,23 @@ def get_powered_by(request, safelink=True): d = gs.settings.license_check_input if d.get('poweredby_name'): if d.get('poweredby_url'): - msg = gettext('powered by {name} based on pretix').format( + msg = format_html( + gettext('powered by {name} based on pretix'), name=d['poweredby_name'], - a_name_attr='href="{}" target="_blank" rel="noopener"'.format( - sl(d['poweredby_url']) if safelink else d['poweredby_url'], - ), - a_attr='href="{}" target="_blank" rel="noopener"'.format( + a_name_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format( + escape(sl(d['poweredby_url'])) if safelink else escape(d['poweredby_url']), + )), + a_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format( sl('https://pretix.eu') if safelink else 'https://pretix.eu', - ) + )) ) else: - msg = gettext('powered by {name} based on pretix').format( + msg = format_html( + gettext('powered by {name} based on pretix'), name=d['poweredby_name'], - a_attr='href="{}" target="_blank" rel="noopener"'.format( + a_attr=mark_safe('href="{}" target="_blank" rel="noopener"'.format( sl('https://pretix.eu') if safelink else 'https://pretix.eu', - ) + )) ) else: msg = gettext('ticketing powered by pretix') % { diff --git a/src/pretix/plugins/paypal/payment.py b/src/pretix/plugins/paypal/payment.py index bdaf8296b..caea843c0 100644 --- a/src/pretix/plugins/paypal/payment.py +++ b/src/pretix/plugins/paypal/payment.py @@ -44,6 +44,7 @@ from django.contrib import messages from django.http import HttpRequest from django.template.loader import get_template from django.urls import reverse +from django.utils.html import format_html from django.utils.timezone import now from django.utils.translation import gettext as __, gettext_lazy as _ from i18nfield.strings import LazyI18nString @@ -112,9 +113,10 @@ class Paypal(BasePaymentProvider): label=_('Client ID'), max_length=80, min_length=80, - help_text=_('{text}').format( + help_text=format_html( + '{text}', text=_('Click here for a tutorial on how to obtain the required keys'), - docs_url='https://docs.pretix.eu/en/latest/user/payments/paypal.html' + docs_url='https://docs.pretix.eu/en/latest/user/payments/paypal.html', ) )), ('secret', diff --git a/src/pretix/plugins/paypal2/payment.py b/src/pretix/plugins/paypal2/payment.py index db3654415..c279ce235 100644 --- a/src/pretix/plugins/paypal2/payment.py +++ b/src/pretix/plugins/paypal2/payment.py @@ -36,6 +36,7 @@ from django.template.loader import get_template from django.templatetags.static import static from django.urls import resolve, reverse from django.utils.crypto import get_random_string +from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.timezone import now from django.utils.translation import gettext as __, gettext_lazy as _ @@ -110,7 +111,8 @@ class PaypalSettingsHolder(BasePaymentProvider): label=_('Client ID'), max_length=80, min_length=80, - help_text=_('{text}').format( + help_text=format_html( + '{text}', text=_('Click here for a tutorial on how to obtain the required keys'), docs_url='https://docs.pretix.eu/en/latest/user/payments/paypal.html' )