Repeated Headers in email message

Hi Django Community! I’m Salvo, a new contributor to this repository. I’m addressing an ongoing issue and wanted to share an update. Originally, there was an issue raised for ensuring that headers aren’t repeated in email messages. I attempted to resolve this problem. Mariusz, rightly, raised some questions about this issue, and there are still two unresolved problems:

  • What should we do with email recipients?
  • If we prevent email messages from having repeated headers, could it be challenging to debug and potentially introduce a regression?

I’ve submitted a PR and aim to find a solution to this problem. My current proposal involves raising an exception when passing two repeated headers and giving precedence to extra_headers

In order to provide a bit more context to this topic, the PR targets ticket 35033 and it’s about duplicated To headers in email messages, which is non RFC 5322 compliant. The RFC says:

The following table indicates limits on the number of times each field may occur in the header section of a message as well as any special limitations on the use of those fields.

   +----------------+--------+------------+----------------------------+
   | Field          | Min    | Max number | Notes                      |
   |                | number |            |                            |
   +----------------+--------+------------+----------------------------+
   | reply-to       | 0      | 1          |                            |
   | to             | 0      | 1          |                            |
   | cc             | 0      | 1          |                            |
   | bcc            | 0      | 1          |                            |

Currently, Django allows to build email messages with more than one To header (see ticket for an example). The first approach to solve this issue was to raise an exception in these cases, but reviewers noticed that there was some work done a few years ago in ticket 17444 to ensure that To passed as extra header param took precedence over to named param (instead of failing). The thing is that when inspecting the unit test added for #17444 (test_to_header), the assertions ensure the following:

        self.assertEqual(message["To"], "mailing-list@example.com")
        self.assertEqual(
            email.to, ["list-subscriber@example.com", "list-subscriber2@example.com"]
        )

but the actual message looks like this:

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Subject
From: bounce@example.com
To: mailing-list@example.com
Date: Thu, 11 Jan 2024 16:31:49 -0000
Message-ID: <170499070904.508585.6085548249520930594@xn--p8s937b>
To: mailing-list@example.com

Content

so email.to is silently ignored. To me, this is a bug, and I think we should raise an error in this case, perhaps with a deprecation process (though I’m unclear if we do deprecation warnings for issues being detected at runtime?).

I did some research and it seems that mail servers’ behavior is either an error or undefined when sending multiple To headers. In particular, Google sent a notification on March 2023 that since April that year, it was going to start rejecting emails with multiple headers (for those headers that only one instance was expected).

1 Like