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

オープン 初心者向け
#285 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
88/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
aws, django, python
領域
backend

調査の方向性

community_base/mail/backends/ses_local.pyから始め、render_deliveryと、_sendからContent.Simple.Subject.Dataに渡される件名に注目してください。6、アポストロフィ、引用符、c、eを含む件名値を使ったパッケージテストを追加し、レンダリングされた件名にHTMLエンティティが含まれず、本文の各パートは引き続き正しくレンダリングされることを確認してください。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
Python
スター
0
フォーク
0
平均マージ
1時間 5分
マージ済み PR(30日)
3

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

DataTalksClub/community-base のほかの issue

DataTalksClub/community-base の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。