The vulnerability is an email injection issue in pretalx, caused by unescaped user-controlled placeholders in email templates. An attacker could register an account with a malicious name (e.g., containing HTML or markdown link syntax) and then trigger an action that sends an email, such as a password reset. The malicious name would be rendered as HTML in the email, allowing the attacker to send phishing emails from a trusted source.
The patch addresses this by implementing a new trust-aware email formatting system. The key changes are:
-
Introduction of pretalx.common.text.formatting.py: This new module provides a safe format_map function that handles trusted and untrusted content differently. It uses a SafeFormatter that prevents common format string abuse and can dispatch on EmailAlternativeString objects which hold separate plain-text and HTML representations of a value.
-
New Placeholder Classes: The patch introduces new placeholder classes in pretalx.mail.placeholders.py (e.g., UntrustedPlainMailTextPlaceholder, UntrustedMarkdownMailTextPlaceholder). These classes are now used for placeholders that render user-controlled content. They ensure that the output is properly escaped for both plain text and HTML emails.
-
Updates to MailTemplate.to_mail: This core function in src/pretalx/mail/models.py was updated to use the new safe format_map and a new render_mail_body function that is aware of the new escaping mechanisms.
-
Updates to Data-providing Functions: Functions that provide content for emails, like Submission.get_content_for_mail, were refactored. The call sites were updated to use new safe methods (e.g., _content_for_mail_placeholder) that return sanitized content wrapped in EmailAlternativeString.
The identified vulnerable functions are central to the process of creating and sending emails with user-provided data. MailTemplate.to_mail is the main entry point for rendering and sending emails. Submission.get_content_for_mail is an example of a function that provided raw, unescaped user data to the templating system. The new format_map function represents the core of the fix, and its absence in a safe form was the root cause of the vulnerability.