Opened 2 years ago

Closed 7 weeks ago

#28726 closed Cleanup/optimization (fixed)

Brackets illegal in DEFAULT_FROM_EMAIL name part.

Reported by: Ciaran Courtney Owned by: Glenn Paquette
Component: Core (Mail) Version: 3.0
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 (7)

comment:1 Changed 2 years 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 2 years 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 2 years 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 2 years ago by Adam (Chainz) Johnson

Cc: Adam (Chainz) Johnson added

Maybe we can add a system check?

comment:5 Changed 2 years 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.

comment:6 Changed 7 weeks ago by Glenn Paquette

Owner: changed from nobody to Glenn Paquette
Status: newassigned

comment:7 Changed 7 weeks ago by felixxm

Resolution: fixed
Status: assignedclosed
Summary: Brackets illegal in DEFAULT_FROM_EMAIL name partBrackets illegal in DEFAULT_FROM_EMAIL name part.
Version: 1.113.0

Changing DEFAULT_FROM_EMAIL documentation doesn't solve it because you can always use from_email argument of EmailMessage (as Tim pointed out).
Moreover this issue was solved in 2628ea95151feb68f43a2a740e6fb0799a94b14b that improved an exception:

  File "/django/django/core/mail/message.py", line 84, in sanitize_address
    raise ValueError('Invalid address "%s"' % addr)
ValueError: Invalid address "[test] Bob <noreply@example.com>"

I don't think that changes in documentation are required.

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