#35033: EmailMessage repeats "To" header if provided via the headers kwargs
-----------------------------------------+--------------------------------
               Reporter:  aalekhpatel07  |          Owner:  nobody
                   Type:  Bug            |         Status:  new
              Component:  Uncategorized  |        Version:  3.2
               Severity:  Normal         |       Keywords:  email, headers
           Triage Stage:  Unreviewed     |      Has patch:  0
    Needs documentation:  0              |    Needs tests:  0
Patch needs improvement:  0              |  Easy pickings:  0
                  UI/UX:  0              |
-----------------------------------------+--------------------------------
 If you create an {{{EmailMessage}}} instance with a `"To"` key in the
 `headers=` kwarg, it attaches the `To` header to the email two times,
 violating [https://datatracker.ietf.org/doc/html/rfc5322#section-3.6 RFC
 5322#3.6].

 My suspicion is that it attaches it the first time from
 {{{extra_headers}}} in  {{{self._set_list_header_if_not_empty(msg, 'To',
 self.to)}}} at
 
[https://github.com/django/django/blob/8fa7c2ae88aee7a2b54a745d25ed38152aad2591/django/core/mail/message.py#L266
 django.core.mail.message:266] and the second time again from
 {{{extra_headers}}} at
 
[https://github.com/django/django/blob/8fa7c2ae88aee7a2b54a745d25ed38152aad2591/django/core/mail/message.py#L282
 django.core.mail.message:282]

 {{{#!python
         message = EmailMessage(
             subject="test subject",
             body="test body",
             from_email="[email protected]",
             to=["[email protected]"],
             headers={
                 "To": ", ".join(["[email protected]", "[email protected]",
 "[email protected]"]),
             },
         )
 }}}

 For example, here is a Python 3.9.18 shell output for the `EmailMessage`
 above that shows the `To` header appears twice.

 {{{#!python
 >>> from django.core.mail import EmailMessage

 >>> message = EmailMessage(subject="test subject", body="test body",
 from_email="[email protected]",to=["[email protected]"], headers={"To": ",
 ".join(["[email protected]", "[email protected]", "[email protected]"])})

 >>> print(list(message.message().raw_items()))
 [('Content-Type', 'text/plain; charset="utf-8"'), ('MIME-Version', '1.0'),
 ('Content-Transfer-Encoding', '7bit'), ('Subject', 'test subject'),
 ('From', '[email protected]'), ('To', '[email protected], [email protected],
 [email protected]'), ('Date', 'Wed, 13 Dec 2023 15:59:31 -0000'),
 ('Message-ID', '<170248317136.759.5778419642073676754@036d358ca984>'),
 ('To', '[email protected], [email protected], [email protected]')]
 }}}


 My current workaround is to override the `EmailMessage::message` method to
 skip adding the {{{To}}}, {{{Cc}}}, {{{From}}}, {{{Reply-To}}} headers the
 second time, since we're already attaching them the first time above. In
 other words:

 {{{#!diff
 @@ -21,7 +21,7 @@
              # Use cached DNS_NAME for performance
              msg['Message-ID'] = make_msgid(domain=DNS_NAME)
          for name, value in self.extra_headers.items():
 -            if name.lower() != 'from':  # From is already handled
 +            if name.lower() not in ('from', 'to', 'cc', 'reply-to'):  #
 These are already handled
                  msg[name] = value
          return msg
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/35033>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018c63f42559-9a86a90d-e509-4aea-85dd-6c48c2dabfb4-000000%40eu-central-1.amazonses.com.

Reply via email to