fix: escape user input in notification content templates - #323
Merged
Gi-ron merged 1 commit intoJul 28, 2026
Merged
Conversation
Discussion thread titles (and other user-controlled context fields — replier_name, author_name, username) were interpolated raw into notification.content via `str.format(**context)`. That output is rendered with Django's `|safe` filter in digest_content.html, which is included by both the email_digest and batched_email body templates, so a `<style>` block in a thread title survived into recipient inboxes as executable CSS on email open — enabling open-tracking, content spoofing, and phishing. Escape at the source: in `get_notification_content`, wrap every context value with `django.utils.html.escape` before `template.format(**context)`, exempting the two structural keys (`p`, `strong`) that content_templates use as HTML tag names. This defends every renderer of `notification.content` in one place. This is the incomplete-patch companion of GHSA-4xv3-5j4x-q8g4 (CVE-2026-42857), which sanitized the post body via `clean_thread_html_body()` but did not cover the title path. Fixes GHSA-rv5w-f4r5-h77g. (cherry picked from commit 08b719ce41bb369fa0cabbe8d0547124e64c8566) (cherry picked from commit 52f2b3b)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
get_notification_contentbeforestr.format(**context), fixing stored CSS injection in digest and batched notification emailsContext
The official fix landed on Ulmo, Verawood and master on July 13, 2026 but did not include Teak. Since
base_notification.pyis unchanged in our Teak branch relative to upstream, this cherry-pick applies cleanly with no conflicts.Discussion thread titles (and other user-controlled context fields —
replier_name,author_name,username) were interpolated raw intonotification.contentviastr.format(**context). That output is rendered with Django's|safefilter indigest_content.html, which is included by both theemail_digestandbatched_emailbody templates, so a<style>block in a thread title survived into recipient inboxes as executable CSS on email open — enabling open-tracking, content spoofing, and phishing.This is the incomplete-patch companion of GHSA-4xv3-5j4x-q8g4 (CVE-2026-42857), which sanitized the post body via
clean_thread_html_body()but did not cover the title path.