DataTalksClub / DataTalksClub/community-base

Mail subjects are rendered with HTML autoescaping and shipped into the SES Subject header

Open Beginner friendly
#285 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
0
Forks
0
Avg merge
9m
Merged PRs (30d)
210

Description

What happens

render_delivery in community_base/mail/backends/ses_local.py renders the subject with Django's default autoescaping:

subject = Template(subject_source).render(Context(full_context))

_send then puts that string straight into Content.Simple.Subject.Data, which is a mail header, not HTML. Any interpolated value containing &, ', ", < or > therefore reaches the inbox with the entity visible.

Rendered proof from a consuming site (AI-Shipping-Labs/website, pinned at v0.5.3), with a synthetic course title Shipping RAG & Agents: Alexey's Buildcamp:

You're enrolled in Shipping RAG &amp; Agents: Alexey&#x27;s Buildcamp — welcome to the AI Shipping Labs community

The escaped subject also propagates past the inbox: it is the string handed to MAIL_SEND_RECORDER, so a consuming site's audit row stores the escaped text too.

Bodies are correct and should not change. body_markdown is escaped, goes through markdown.markdown(...), and the HTML part renders the character correctly; the text part is derived by _PlainTextHTMLParser(convert_charrefs=True), which decodes the entities back. Only the subject is wrong.

Static template text is unaffected, because autoescaping only touches interpolated values — a literal apostrophe in the template source ships fine today. This is only visible once a variable carries one of those characters, which makes it a latent defect in every consuming site rather than a currently visible one.

Suggested fix

Render the subject with autoescaping off, since its destination is not an HTML document:

subject = Template(subject_source).render(Context(full_context, autoescape=False))

Leave the body rendering exactly as it is.

An alternative is to unescape at the SES boundary in _send, but that is lossy for a subject that legitimately contains the literal text &amp;, so rendering the subject as non-HTML at the point of render is the better mechanism.

Worth a package test that renders a subject template with a value containing &, ', ", < and > and asserts the rendered subject contains no HTML entity, plus an assertion that the body parts still render the character correctly.

Consuming-site context

AI-Shipping-Labs/website issue #1748 covers the same defect on the site side. That site has its own second renderer with the same bug, which it is fixing locally, and while pinned to v0.5.3 it will neutralize the package path from its MAIL_TEMPLATE_OVERRIDE_LOADER hook by wrapping the subject source in {% autoescape off %}. That wrapper stays a harmless no-op once this is fixed upstream, so the two changes do not conflict and the upgrade needs no coordination.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in community_base/mail/backends/ses_local.py, focusing on render_delivery and the subject passed from _send to Content.Simple.Subject.Data. Add a package test using subject values containing &, apostrophe, quotes, < and >, and verify the rendered subject has no HTML entities while the body parts still render correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, django, python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.