Commit Graph

744 Commits

Author SHA1 Message Date
Brian Schubert d4df3c55e4
[3.9] gh-80222: Fix email address header folding with long quoted-string (GH-122753) (GH-129111) (GH-132371)
Email generators using email.policy.default could incorrectly omit the
quote ('"') characters from a quoted-string during header refolding,
leading to invalid address headers and enabling header spoofing. This
change restores the quote characters on a bare-quoted-string as the
header is refolded, and escapes backslash and quote chars in the string.

(cherry picked from commit 5aaf416858)
(cherry picked from commit a4ef689ce6)

Co-authored-by: R. David Murray <rdmurray@bitdance.com>
Co-authored-by: Mike Edmunds <medmunds@gmail.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
2025-06-02 17:57:06 +02:00
Petr Viktorin 9a31386eec
[3.9] gh-121284: Fix email address header folding with parsed encoded-word (GH-122754) (GH-131412)
Email generators using email.policy.default may convert an RFC 2047
encoded-word to unencoded form during header refolding. In a structured
header, this could allow 'specials' chars outside a quoted-string,
leading to invalid address headers and enabling spoofing. This change
ensures a parsed encoded-word that contains specials is kept as an
encoded-word while the header is refolded.

[Better fix from @bitdancer.]

(cherry picked from commit 295b53df2a)

Co-authored-by: Mike Edmunds <medmunds@gmail.com>
Co-authored-by: R David Murray <rdmurray@bitdance.com>
2025-04-03 18:27:33 +02:00
Petr Viktorin ee953f2b8f
[3.9] [CVE-2023-27043] gh-102988: Reject malformed addresses in email.parseaddr() (GH-111116) (#123769)
Detect email address parsing errors and return empty tuple to
indicate the parsing error (old API). Add an optional 'strict'
parameter to getaddresses() and parseaddr() functions. Patch by
Thomas Dwyer.

(cherry picked from commit 4a153a1d3b)

Co-authored-by: Victor Stinner <vstinner@python.org>
Co-Authored-By: Thomas Dwyer <github@tomd.tel>
2024-09-06 13:13:54 +02:00
Łukasz Langa f7be505d13
[3.9] gh-121650: Encode newlines in headers, and verify headers are sound (GH-122233) (#122610)
Per RFC 2047:

> [...] these encoding schemes allow the
> encoding of arbitrary octet values, mail readers that implement this
> decoding should also ensure that display of the decoded data on the
> recipient's terminal will not cause unwanted side-effects

It seems that the "quoted-word" scheme is a valid way to include
a newline character in a header value, just like we already allow
undecodable bytes or control characters.
They do need to be properly quoted when serialized to text, though.

This should fail for custom fold() implementations that aren't careful
about newlines.

(cherry picked from commit 0976339818)

Co-authored-by: Petr Viktorin <encukou@gmail.com>
Co-authored-by: Bas Bloemsaat <bas@bloemsaat.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
2024-09-04 17:39:02 +02:00
Miss Islington (bot) bab6954482
[3.9] gh-77630: Change Charset to charset (GH-92439) (GH-92477)
(cherry picked from commit 8f29318079)


Co-authored-by: slateny <46876382+slateny@users.noreply.github.com>

Automerge-Triggered-By: GH:serhiy-storchaka
2022-05-08 08:28:18 -07:00
Miss Islington (bot) 3d0a5f73f5
bpo-43323: Fix UnicodeEncodeError in the email module (GH-32137)
It was raised if the charset itself contains characters not encodable
in UTF-8 (in particular \udcxx characters representing non-decodable
bytes in the source).
(cherry picked from commit e91dee87ed)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
2022-04-30 05:31:37 -07:00
Miss Islington (bot) 5638618845
bpo-45239: Fix parsedate_tz when time has more than 2 dots in it (GH-28452) (GH-28928)
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
(cherry picked from commit b9e687618d)

Co-authored-by: Ben Hoyt <benhoyt@gmail.com>
2021-10-13 18:58:37 +02:00
Serhiy Storchaka e09dd8aafd
[3.9] bpo-45060: Get rid of few uses of the equality operators with None (GH-28087). (GH-28093)
(cherry picked from commit 3c65457156)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
2021-09-01 09:51:01 +03:00
Miss Islington (bot) 2cdbd3b8b2
bpo-45001: Make email date parsing more robust against malformed input (GH-27946) (GH-27973)
Various date parsing utilities in the email module, such as
email.utils.parsedate(), are supposed to gracefully handle invalid
input, typically by raising an appropriate exception or by returning
None.

The internal email._parseaddr._parsedate_tz() helper used by some of
these date parsing routines tries to be robust against malformed input,
but unfortunately it can still crash ungracefully when a non-empty but
whitespace-only input is passed. This manifests as an unexpected
IndexError.

In practice, this can happen when parsing an email with only a newline
inside a ‘Date:’ header, which unfortunately happens occasionally in the
real world.

Here's a minimal example:

    $ python
    Python 3.9.6 (default, Jun 30 2021, 10:22:16)
    [GCC 11.1.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import email.utils
    >>> email.utils.parsedate('foo')
    >>> email.utils.parsedate(' ')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/email/_parseaddr.py", line 176, in parsedate
        t = parsedate_tz(data)
      File "/usr/lib/python3.9/email/_parseaddr.py", line 50, in parsedate_tz
        res = _parsedate_tz(data)
      File "/usr/lib/python3.9/email/_parseaddr.py", line 72, in _parsedate_tz
        if data[0].endswith(',') or data[0].lower() in _daynames:
    IndexError: list index out of range

The fix is rather straight-forward: guard against empty lists, after
splitting on whitespace, but before accessing the first element.
(cherry picked from commit 989f6a3800)

Co-authored-by: wouter bolsterlee <wouter@bolsterl.ee>
2021-08-26 17:48:20 +02:00
Miss Islington (bot) 395f4c7fbf
bpo-41402: Fix email ContentManager calling .encode() on bytes (GH-21631) (GH-27687)
(cherry picked from commit b33186bc43)

Co-authored-by: Johannes Reiff <mail@jreiff.de>
2021-08-10 00:34:58 +02:00
Miss Islington (bot) 0f42b726c8
bpo-42892: fix email multipart attribute error (GH-26903) (GH-27493)
(cherry picked from commit e3f877c32d)

Co-authored-by: andrei kulakov <andrei.avk@gmail.com>
2021-07-30 19:30:58 +02:00
Miss Islington (bot) 9ee12cf325
bpo-27513: email.utils.getaddresses() now handles Header objects (GH-13797) (#27245)
getaddresses() should be able to handle a Header object if passed
one.

Co-authored-by: Łukasz Langa <lukasz@langa.pl>
(cherry picked from commit 89f4c34797)

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
2021-07-19 19:28:56 +02:00
Miss Islington (bot) 67b3a99953
bpo-44395: Fix MIMEPart.as_string to pass unixfrom properly (GH-26685)
(cherry picked from commit 30f7a77f35)

Co-authored-by: Dong-hee Na <donghee.na@python.org>
2021-06-21 07:27:42 -07:00
Miss Skeleton (bot) 72ce82abcf
bpo-27321 Fix email.generator.py to not replace a non-existent header. (GH-18074)
This PR replaces GH-1977. The reason for the replacement is two-fold.

The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit.

Also the tests are different. The test_nonascii_as_string_without_cte test in GH-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness.

Automerge-Triggered-By: @warsaw
(cherry picked from commit bf838227c3)

Co-authored-by: Mark Sapiro <mark@msapiro.net>
2020-10-19 16:11:37 -07:00
Miss Skeleton (bot) 6d40943e34
Typo fix - "mesasge" should be "message" (GH-22498)
* Correct at 2 places in email module
(cherry picked from commit 9cd01ece78)

Co-authored-by: Hansraj Das <raj.das.136@gmail.com>
2020-10-02 13:43:44 -07:00
Miss Islington (bot) e68978978f
bpo-40597: Allow email.contextmanager set_content() to set a null string. (GH-20542)
(cherry picked from commit 4fa61a7732)

Co-authored-by: Mark Sapiro <mark@msapiro.net>
2020-07-08 14:21:00 -07:00
Miss Islington (bot) 83e54debac
Improve readability of `formataddr` docstring (GH-20963)
For me as a non native English speaker, the sentence with its embedded clause was very hard to understand.

modified:   Lib/email/utils.py

Automerge-Triggered-By: @csabella
(cherry picked from commit 66a65ba43c)

Co-authored-by: Jürgen Gmach <juergen.gmach@googlemail.com>
2020-06-19 05:18:44 -07:00
Miss Islington (bot) a6ae02d7e9
bpo-39040: Fix parsing of email mime headers with whitespace between encoded-words. (gh-17620)
* bpo-39040: Fix parsing of email headers with encoded-words inside a quoted string.

It is fairly common to find malformed mime headers (especially content-disposition
headers) where the parameter values, instead of being encoded to RFC
standards, are "encoded" by doing RFC 2047 "encoded word" encoding, and
then enclosing the whole thing in quotes.  The processing of these malformed
headers was incorrectly leaving the spaces between encoded words in the decoded
text (whitespace between adjacent encoded words is supposed to be stripped on
decoding).  This changeset fixes the encoded word processing inside quoted strings
(bare-quoted-string) to do correct RFC 2047 decoding by stripping that
whitespace.
(cherry picked from commit 21017ed904)

Co-authored-by: Abhilash Raj <maxking@users.noreply.github.com>
2020-05-29 04:43:06 -07:00
Arkadiusz Hiler 6f2f475d5a
bpo-40597: email: Use CTE if lines are longer than max_line_length consistently (gh-20038)
raw_data_manager (default for EmailPolicy, EmailMessage)
does correct wrapping of 'text' parts as long as the message contains
characters outside of 7bit US-ASCII set: base64 or qp
Content-Transfer-Encoding is applied if the lines would be too long
without it.  It did not, however, do this for ascii-only text,
which could result in lines that were longer than
policy.max_line_length or even the rfc 998  maximum.

This changeset fixes the heuristic so that if lines are longer than
policy.max_line_length, it will always apply a
content-transfer-encoding so that the lines are wrapped correctly.
2020-05-13 20:53:26 -04:00
Ashwin Ramaswami 614f17211c
bpo-39073: validate Address parts to disallow CRLF (#19007)
Disallow CR or LF in email.headerregistry.Address arguments to guard against header injection attacks.
2020-03-29 20:38:41 -04:00
Abhilash Raj 3ae4ea1931
bpo-38708: email: Fix a potential IndexError when parsing Message-ID (GH-17504)
Fix a potential IndexError when passing an empty value to the message-id
parser. Instead, HeaderParseError should be raised.
2019-12-08 17:37:34 -08:00
Abhilash Raj 68157da8b4
bpo-38698: Add a new InvalidMessageID token to email header parser. (GH-17503)
This adds a new InvalidMessageID token to the email header parser which can be
used to represent invalid message-id headers in the parse tree.
2019-12-08 17:35:38 -08:00
Claudiu Popa bb815499af bpo-38698: Prevent UnboundLocalError to pop up in parse_message_id (GH-17277)
parse_message_id() was improperly using a token defined inside an exception
handler, which was raising `UnboundLocalError` on parsing an invalid value.




https://bugs.python.org/issue38698
2019-12-04 19:14:26 -08:00
Andrei Troie 65dcc8a8dc bpo-38332: Catch KeyError from unknown cte in encoded-word. (GH-16503)
KeyError should cause a failure in parsing the encoded word and should be caught and raised as a _InvalidEWError instead.
2019-10-05 09:19:15 -07:00
Michael Selik 2702638eab bpo-34002: Minor efficiency and clarity improvements in email package. (GH-7999)
* Check intersection of two sets explicitly

Comparing ``len(a) > ``len(a - b)`` is essentially looking for an
intersection between the two sets. If set ``b`` does not intersect ``a``
then ``len(a - b)`` will be equal to ``len(a)``. This logic is more
clearly expressed as ``a & b``.

* Change while/pop to a for-loop

Copying the list, then repeatedly popping the first element was
unnecessarily slow. I also cleaned up a couple other inefficiencies.
There's no need to unpack a tuple, then re-pack and append it. The list
can be created with the first element instead of empty. Secondly, the
``endswith`` method returns a bool, so there's no need for an if-
statement to set ``encoding`` to True or False.

* Use set.intersection to check for intersections

``a.intersection(b)`` method is more clear of purpose than ``not
a.isdisjoint(b)`` and avoids an unnecessary set construction that ``a &
set(b)`` performs.

* Use not isdisjoint instead of intersection

While it reads slightly worse, the isdisjoint method will stop when it
finds a counterexample and returns a bool, rather than looping over the
entire iterable and constructing a new set.
2019-09-19 20:25:55 -07:00
Ashwin Ramaswami c5b242f87f bpo-37764: Fix infinite loop when parsing unstructured email headers. (GH-15239)
Fixes a case in which email._header_value_parser.get_unstructured hangs the system for some invalid headers. This covers the cases in which the header contains either:
- a case without trailing whitespace
- an invalid encoded word

https://bugs.python.org/issue37764

This fix should also be backported to 3.7 and 3.8


https://bugs.python.org/issue37764
2019-08-31 08:25:35 -07:00
bsiem df0c21ff46 bpo-37482: Fix email address name with encoded words and special chars (GH-14561)
Special characters in email address header display names are normally
put within double quotes. However, encoded words (=?charset?x?...?=) are
not allowed withing double quotes. When the header contains a word with
special characters and another word that must be encoded, the first one
must also be encoded.

In the next example, the display name in the From header is quoted and
therefore the comma is allowed; in the To header, the comma is not
within quotes and not encoded, which is not allowed and therefore
rejected by some mail servers.

From: "Foo Bar, France" <foo@example.com>
To: Foo Bar, =?utf-8?q?Espa=C3=B1a?= <foo@example.com>





https://bugs.python.org/issue37482
2019-08-21 16:00:39 -07:00
Abhilash Raj 09a1872a80 bpo-32178: Fix IndexError trying to parse 'To' header starting with ':'. (GH-15044)
This should fix the IndexError trying to retrieve `DisplayName.display_name` and `DisplayName.value` when the `value` is basically an empty string.




https://bugs.python.org/issue32178
2019-08-11 13:45:09 -07:00
Serhiy Storchaka 662db125cd
bpo-37685: Fixed __eq__, __lt__ etc implementations in some classes. (GH-14952)
They now return NotImplemented for unsupported type of the other operand.
2019-08-08 08:42:54 +03:00
Min ho Kim 96e12d5f4f Fix typos in docs, comments and test assert messages (#14872) 2019-07-21 16:12:33 -04:00
jpic 8cb65d1381 bpo-34155: Dont parse domains containing @ (GH-13079)
Before:
    
        >>> email.message_from_string('From: a@malicious.org@important.com', policy=email.policy.default)['from'].addresses
        (Address(display_name='', username='a', domain='malicious.org'),)
    
        >>> parseaddr('a@malicious.org@important.com')
        ('', 'a@malicious.org')
    
    After:
    
        >>> email.message_from_string('From: a@malicious.org@important.com', policy=email.policy.default)['from'].addresses
        (Address(display_name='', username='', domain=''),)
    
        >>> parseaddr('a@malicious.org@important.com')
        ('', 'a@')




https://bugs.python.org/issue34155
2019-07-17 14:54:25 -07:00
Abhilash Raj 719a062bcb Fix IndexError when parsing unexpectedly ending quoted-string. (GH-14813)
This exception was caused because the input ended unexpectedly with only one
single quote instead of a pair with some value inside it.
2019-07-17 09:48:52 -07:00
Abhilash Raj a4a994bd3e bpo-37461: Fix infinite loop in parsing of specially crafted email headers (GH-14794)
* bpo-37461: Fix infinite loop in parsing of specially crafted email headers.

Some crafted email header would cause the get_parameter method to run in an
infinite loop causing a DoS attack surface when parsing those headers. This
patch fixes that by making sure the DQUOTE character is handled to prevent
going into an infinite loop.
2019-07-17 09:44:27 -07:00
Paul Ganssle f69d5c6198 Fix infinite loop in email folding logic (GH-12732)
As far as I can tell, this infinite loop would be triggered if:

1. The value being folded contains a single word (no spaces) longer than
   max_line_length
2. The max_line_length is shorter than the encoding's name + 9
   characters.

bpo-36564: https://bugs.python.org/issue36564
2019-07-16 10:50:01 -07:00
Abhilash Raj 7213df7bbf bpo-29412: Fix indexError when parsing a header value ending unexpectedly (GH-14387)
* patched string index out of range error in get_word function of _header_value_parser.py and created tests in test__header_value_parser.py for CFWS.
* Raise HeaderParseError instead of continuing when parsing a word.
2019-06-26 13:13:02 -07:00
Abhilash Raj 02257012f6 bpo-33972: Fix EmailMessage.iter_attachments raising AttributeError. (GH-14119)
* bpo-33972: Fix EmailMessage.iter_attachments raising AttributeError.

When certain malformed messages have content-type set to 'mulitpart/*' but
still have a single part body, iter_attachments can raise AttributeError. This
patch fixes it by returning a None value instead when the body is single part.
2019-06-25 10:03:19 -07:00
websurfer5 f6713e84af bpo-36520: Email header folded incorrectly (#13608)
* bpo-36520: reset the encoded word offset when starting a new
line during an email header folding operation

* 📜🤖 Added by blurb_it.

* bpo-36520: add an additional test case, and provide descriptive
comments for the test_folding_with_utf8_encoding_* tests

* bpo-36520: fix whitespace issue

* bpo-36520: changes per reviewer request -- remove extraneous
backslashes; add whitespace between terminating quotes and
line-continuation backslashes; use "bpo-" instead of
"issue #" in comments
2019-06-06 12:53:27 -07:00
Abhilash Raj 66c4f3f38b bpo-21315: Fix parsing of encoded words with missing leading ws. (#13425)
* bpo-21315: Fix parsing of encoded words with missing leading ws.

Because of missing leading whitespace, encoded word would get parsed as
unstructured token. This patch fixes that by looking for encoded words when
splitting tokens with whitespace.

Missing trailing whitespace around encoded word now register a defect
instead.

Original patch suggestion by David R. Murray on bpo-21315.
2019-06-05 09:56:33 -07:00
Abhilash Raj aa79707262 bpo-30835: email: Fix AttributeError when parsing invalid CTE (GH-13598)
* bpo-30835: email: Fix AttributeError when parsing invalid Content-Transfer-Encoding

Parsing an email containing a multipart Content-Type, along with a
Content-Transfer-Encoding containing an invalid (non-ASCII-decodable) byte
will fail. email.feedparser.FeedParser._parsegen() gets the header and
attempts to convert it to lowercase before comparing it with the accepted
encodings, but as the header contains an invalid byte, it's returned as a
Header object rather than a str.

Cast the Content-Transfer-Encoding header to a str to avoid this.

Found using the AFL fuzzer.

Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Andrew Donnellan <andrew@donnellan.id.au>

* Add email and NEWS entry for the bugfix.
2019-06-04 11:00:47 -07:00
Abhilash Raj 46d88a1131 bpo-35805: Add parser for Message-ID email header. (GH-13397)
* bpo-35805: Add parser for Message-ID header.

This parser is based on the definition of Identification Fields from RFC 5322
Sec 3.6.4.

This should also prevent folding of Message-ID header using RFC 2047 encoded
words and hence fix bpo-35805.

* Prevent folding of non-ascii message-id headers.
* Add fold method to MsgID token to prevent folding.
2019-06-04 10:41:34 -07:00
Xtreak 0d70227e41 Fix typos in docs and docstrings (GH-13745) 2019-06-03 01:12:33 +02:00
Batuhan Taşkaya ef5bb25e2d bpo-27737: Allow whitespace only headers encoding (#13478) 2019-05-22 21:13:16 -04:00
Abhilash Raj feac6cd775 bpo-33524: Fix the folding of email header when max_line_length is 0 or None (#13391)
and there are non-ascii characters in the header.
2019-05-17 15:28:44 -04:00
Krzysztof Wojcik c1f5667be1 bpo-33529, email: Fix infinite loop in email header encoding (GH-12020) 2019-05-14 18:55:23 +02:00
Jens Troeger 45b2f8893c bpo-34424: Handle different policy.linesep lengths correctly. (#8803) 2019-05-13 21:07:39 -04:00
Serhiy Storchaka 96aeaec647
bpo-36793: Remove unneeded __str__ definitions. (GH-13081)
Classes that define __str__ the same as __repr__ can
just inherit it from object.
2019-05-06 22:29:40 +03:00
Inada Naoki c95404ff65
email: use dict instead of OrderedDict (GH-11709) 2019-02-05 17:05:43 +09:00
Serhiy Storchaka 34fd4c2019
bpo-35133: Fix mistakes when concatenate string literals on different lines. (GH-10284)
Two kind of mistakes:

1. Missed space. After concatenating there is no space between words.

2. Missed comma. Causes unintentional concatenating in a list of strings.
2018-11-05 16:20:25 +02:00
Dong-hee Na 8fe9eed937 bpo-33476: Fix _header_value_parser when address group is missing final ';' (GH-7484) 2018-07-28 13:55:11 +01:00
Tal Einat c3f55be7dd
bpo-27397: Make email module properly handle invalid-length base64 strings (#7583)
When attempting to base64-decode a payload of invalid length (1 mod 4),
properly recognize and handle it.  The given data will be returned as-is,
i.e. not decoded, along with a new defect, InvalidBase64LengthDefect.
2018-06-12 15:46:22 +03:00