When a header with an encoded (QP or Base64) display_name is refolded, it may lose (some of) its encoding. If it then contains illegal "atext" tokens, an invalid header will result.
For example, From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <abc@example.com> will become From: a, 123456789012345678901234567890123456 <abc@example.com> This contains a comma character which needs to be quoted: correct rendering would be From: "a, 123456789012345678901234567890123456" <abc@example.com>. Note that this example isn't even folded to multiple lines, since the decoded text is short enough to fit in one line.
This can be triggered by BytesParser(policy=policy.default).parsebytes("From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <abc@example.com>").as_bytes(), but the offending code seems to be in or below email.policy.EmailPolicy.fold. See attached file for examples with and without folding.
Ping! This still reproduces on 3.14.8 and 3.15.0rc3. An encoded-word display name that decodes to ASCII containing specials is refolded without quoting:
$ python3.15
Python 3.15.0rc3 (main, Oct 3 2026, 05:15:06) [GCC 13.3.0] on linux
>>> import email.message, email.policy
... m = email.message.EmailMessage(policy=email.policy.default)
... m["To"] ="=?utf-8?q?x=2C_y=40example=2Ecom?= <to@example.com>"
... print(m.as_bytes())
...
b'To: x, y@example.com <to@example.com>\n\n'
$ python3.14
Python 3.14.8 (main, Oct 1 2026, 15:42:08) [GCC 13.3.0] on linux
>>> import email.message, email.policy
... m = email.message.EmailMessage(policy=email.policy.default)
... m["To"] ="=?utf-8?q?x=2C_y=40example=2Ecom?= <to@example.com>"
... print(m.as_bytes())
...
b'To: x, y@example.com <to@example.com>\n\n'
The header parses as a single mailbox but serializes as one that re-parses differently. This behavior has also been (incorrectly) reported to the Django security team; the root cause is here, so fixing it upstream would address those reports at the source.
PR #134271 fixes this and has been approved by @medmunds, who maintains much of Django's email handling and is familiar with this area of the email package. Currently it is awaiting core review but marked stale, I can confirm it does solve the reported issue though.
Activity
EmilStyrke commented on Mar 19, 2021
When a header with an encoded (QP or Base64) display_name is refolded, it may lose (some of) its encoding. If it then contains illegal "atext" tokens, an invalid header will result.
For example, From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <abc@example.com> will become From: a, 123456789012345678901234567890123456 <abc@example.com> This contains a comma character which needs to be quoted: correct rendering would be From: "a, 123456789012345678901234567890123456" <abc@example.com>. Note that this example isn't even folded to multiple lines, since the decoded text is short enough to fit in one line.
This can be triggered by BytesParser(policy=policy.default).parsebytes("From: =?utf-8?Q?a=2C=20123456789012345678901234567890123456?= <abc@example.com>").as_bytes(), but the offending code seems to be in or below email.policy.EmailPolicy.fold. See attached file for examples with and without folding.
brychcy commented on May 12, 2025
See #121284
medmunds commented on May 26, 2025
rfc2047 RFC-2047 encoded-word
nessita commented on Oct 8, 2026
Ping! This still reproduces on 3.14.8 and 3.15.0rc3. An encoded-word display name that decodes to ASCII containing specials is refolded without quoting:
The header parses as a single mailbox but serializes as one that re-parses differently. This behavior has also been (incorrectly) reported to the Django security team; the root cause is here, so fixing it upstream would address those reports at the source.
PR #134271 fixes this and has been approved by @medmunds, who maintains much of Django's email handling and is familiar with this area of the email package. Currently it is awaiting core review but marked stale, I can confirm it does solve the reported issue though.
bitdancer commented on Oct 8, 2026
Huh. I thought I merged that a while ago. Oops.
I've updated the PR. Can you give me a quick once over on it to make sue I didn't make any stupid typos, and I'll merge it?
gh-87720 Fix additional header refolding-quoting edge case (#134271)
[3.14] gh-87720 Fix additional header refolding-quoting edge case (GH…
medmunds commented on Oct 9, 2026
Closed by #134271.
[3.15] gh-87720 Fix additional header refolding-quoting edge case (GH…
[3.12] gh-87720 Fix additional header refolding-quoting edge case (GH…
[3.13] gh-87720 Fix additional header refolding-quoting edge case (GH…
[3.11] gh-87720 Fix additional header refolding-quoting edge case (GH…