Opened 4 weeks ago

Last modified 3 weeks ago

#28726 new Cleanup/optimization

Brackets illegal in DEFAULT_FROM_EMAIL name part

Reported by: Ciaran Courtney Owned by: nobody
Component: Core (Mail) Version: 1.11
Severity: Normal Keywords: email DEFAULT_FROM_EMAIL
Cc: Adam (Chainz) Johnson Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Jani Sumak)

Using DEFAULT_FROM_EMAIL = '[test] Bob <noreply@example.com>' will fail in django.core.mail.message.sanitize_address() at parseaddr(addr)

Possibly other characters are illegal. The docs don't mention the use of DEFAULT_FROM_EMAIL in this way, perhaps documentation can cover it.

Change History (5)

comment:1 Changed 4 weeks ago by Jani Sumak

Description: modified (diff)
Triage Stage: UnreviewedAccepted

If from_email is not provided, EmailMessage or EmailMultiAlternatives will use DEFAULT_FROM_EMAIL. If DEFAULT_FROM_EMAIL is not a tuple sanitize_address will pass DEFAULT_FROM_EMAIL to the function parseaddr from the email module in the standard library. parseaddrwill then try to parse RFC 2822 addresses.

Space and "(),:;<>@[\] characters are allowed with restrictions (https://stackoverflow.com/a/2049510/4819353). If you pass a suqare bracket [ to parseaddr it will return someting like this: [('', ''), ('', 'test'), ('', ''), ('Bob', 'noreply@example.com')]. Since sanitize_addresswill use only the first element from the returned list, you will get an error.

I suggest that the documentation mentions some of this.

DEFAULT_FROM_EMAIL¶
...

The value should be a tuple containing two strings, `(name, address)`,  or a string in the form of `name <email@example.com>`.

comment:2 Changed 4 weeks ago by Jonatas CD

Should also the default value be changed to a tuple?
Seems somewhat more coherent to me.
What do you think?

comment:3 Changed 3 weeks ago by Tim Graham

Easy pickings: unset
Type: BugCleanup/optimization

Changing the default value to a tuple could be backwards incompatible.

I'm not sure if documentation is needed here, however, it could be helpful to improve the exception:

  File "/home/tim/code/django/tests/mail/tests.py", line 845, in test_html_send_mail
    send_mail('Subject', 'Content', '[test] Bob <noreply@example.com>', ['nobody@example.com'], html_message='HTML Content')
  File "/home/tim/code/django/django/core/mail/__init__.py", line 62, in send_mail
    return mail.send()
  File "/home/tim/code/django/django/core/mail/message.py", line 349, in send
    return self.get_connection(fail_silently).send_messages([self])
  File "/home/tim/code/django/django/core/mail/backends/smtp.py", line 111, in send_messages
    sent = self._send(message)
  File "/home/tim/code/django/django/core/mail/backends/smtp.py", line 123, in _send
    from_email = sanitize_address(email_message.from_email, encoding)
  File "/home/tim/code/django/django/core/mail/message.py", line 161, in sanitize_address
    address = Address(nm, addr_spec=addr)
  File "/home/tim/code/cpython/Lib/email/headerregistry.py", line 42, in __init__
    a_s, rest = parser.get_addr_spec(addr_spec)
  File "/home/tim/code/cpython/Lib/email/_header_value_parser.py", line 1986, in get_addr_spec
    token, value = get_local_part(value)
  File "/home/tim/code/cpython/Lib/email/_header_value_parser.py", line 1798, in get_local_part
    if value[0] in CFWS_LEADER:
IndexError: string index out of range

That might involve patching cpython rather than Django.

comment:4 Changed 3 weeks ago by Adam (Chainz) Johnson

Cc: Adam (Chainz) Johnson added

Maybe we can add a system check?

comment:5 Changed 3 weeks ago by Tim Graham

I also considered suggesting a system check but I doubt the issue is common enough to justify it. The problem could also happen when using the from_email argument of EmailMessage and improving the exception will address that.

Note: See TracTickets for help on using tickets.
Back to Top