From: Josef Schlehofer Date: Mon, 30 Sep 2019 15:22:00 +0000 (+0200) Subject: python3: fix CVE-2019-16056 and delete two patches X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=126cdd7c6b577840b078b6c7abd2d434a7c86312;p=feed%2Fpackages.git python3: fix CVE-2019-16056 and delete two patches Signed-off-by: Josef Schlehofer --- diff --git a/lang/python/python3/patches/025-bpo-34155-Dont-parse-domains-containing-GH-13079-GH-.patch b/lang/python/python3/patches/025-bpo-34155-Dont-parse-domains-containing-GH-13079-GH-.patch new file mode 100644 index 0000000000..dfee58a9d4 --- /dev/null +++ b/lang/python/python3/patches/025-bpo-34155-Dont-parse-domains-containing-GH-13079-GH-.patch @@ -0,0 +1,134 @@ +From 13a19139b5e76175bc95294d54afc9425e4f36c9 Mon Sep 17 00:00:00 2001 +From: "Miss Islington (bot)" + <31488909+miss-islington@users.noreply.github.com> +Date: Fri, 9 Aug 2019 08:22:19 -0700 +Subject: [PATCH] bpo-34155: Dont parse domains containing @ (GH-13079) + (GH-14826) + +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 +(cherry picked from commit 8cb65d1381b027f0b09ee36bfed7f35bb4dec9a9) + +Co-authored-by: jpic +--- + Lib/email/_header_value_parser.py | 2 ++ + Lib/email/_parseaddr.py | 11 ++++++++++- + Lib/test/test_email/test__header_value_parser.py | 10 ++++++++++ + Lib/test/test_email/test_email.py | 14 ++++++++++++++ + .../2019-05-04-13-33-37.bpo-34155.MJll68.rst | 1 + + 5 files changed, 37 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst + +diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py +index 737951e4b1..bc9c9b6241 100644 +--- a/Lib/email/_header_value_parser.py ++++ b/Lib/email/_header_value_parser.py +@@ -1561,6 +1561,8 @@ def get_domain(value): + token, value = get_dot_atom(value) + except errors.HeaderParseError: + token, value = get_atom(value) ++ if value and value[0] == '@': ++ raise errors.HeaderParseError('Invalid Domain') + if leader is not None: + token[:0] = [leader] + domain.append(token) +diff --git a/Lib/email/_parseaddr.py b/Lib/email/_parseaddr.py +index cdfa3729ad..41ff6f8c00 100644 +--- a/Lib/email/_parseaddr.py ++++ b/Lib/email/_parseaddr.py +@@ -379,7 +379,12 @@ class AddrlistClass: + aslist.append('@') + self.pos += 1 + self.gotonext() +- return EMPTYSTRING.join(aslist) + self.getdomain() ++ domain = self.getdomain() ++ if not domain: ++ # Invalid domain, return an empty address instead of returning a ++ # local part to denote failed parsing. ++ return EMPTYSTRING ++ return EMPTYSTRING.join(aslist) + domain + + def getdomain(self): + """Get the complete domain name from an address.""" +@@ -394,6 +399,10 @@ class AddrlistClass: + elif self.field[self.pos] == '.': + self.pos += 1 + sdlist.append('.') ++ elif self.field[self.pos] == '@': ++ # bpo-34155: Don't parse domains with two `@` like ++ # `a@malicious.org@important.com`. ++ return EMPTYSTRING + elif self.field[self.pos] in self.atomends: + break + else: +diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py +index a2c900fa7f..02ef3e1006 100644 +--- a/Lib/test/test_email/test__header_value_parser.py ++++ b/Lib/test/test_email/test__header_value_parser.py +@@ -1418,6 +1418,16 @@ class TestParser(TestParserMixin, TestEmailBase): + self.assertEqual(addr_spec.domain, 'example.com') + self.assertEqual(addr_spec.addr_spec, 'star.a.star@example.com') + ++ def test_get_addr_spec_multiple_domains(self): ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@a.star@example.com') ++ ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@a@example.com') ++ ++ with self.assertRaises(errors.HeaderParseError): ++ parser.get_addr_spec('star@172.17.0.1@example.com') ++ + # get_obs_route + + def test_get_obs_route_simple(self): +diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py +index f97ccc6711..68d0522799 100644 +--- a/Lib/test/test_email/test_email.py ++++ b/Lib/test/test_email/test_email.py +@@ -3035,6 +3035,20 @@ class TestMiscellaneous(TestEmailBase): + self.assertEqual(utils.parseaddr('<>'), ('', '')) + self.assertEqual(utils.formataddr(utils.parseaddr('<>')), '') + ++ def test_parseaddr_multiple_domains(self): ++ self.assertEqual( ++ utils.parseaddr('a@b@c'), ++ ('', '') ++ ) ++ self.assertEqual( ++ utils.parseaddr('a@b.c@c'), ++ ('', '') ++ ) ++ self.assertEqual( ++ utils.parseaddr('a@172.17.0.1@c'), ++ ('', '') ++ ) ++ + def test_noquote_dump(self): + self.assertEqual( + utils.formataddr(('A Silly Person', 'person@dom.ain')), +diff --git a/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst b/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst +new file mode 100644 +index 0000000000..50292e29ed +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2019-05-04-13-33-37.bpo-34155.MJll68.rst +@@ -0,0 +1 @@ ++Fix parsing of invalid email addresses with more than one ``@`` (e.g. a@b@c.com.) to not return the part before 2nd ``@`` as valid email address. Patch by maxking & jpic. +-- +2.20.1 + diff --git a/lang/python/python3/patches/025-bpo-37461-Fix-infinite-loop-in-parsing-of-specially-.patch b/lang/python/python3/patches/025-bpo-37461-Fix-infinite-loop-in-parsing-of-specially-.patch deleted file mode 100644 index c61ba8b04a..0000000000 --- a/lang/python/python3/patches/025-bpo-37461-Fix-infinite-loop-in-parsing-of-specially-.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 391511ccaaf0050970dfbe95bf2df1bcf6c33440 Mon Sep 17 00:00:00 2001 -From: "Miss Islington (bot)" - <31488909+miss-islington@users.noreply.github.com> -Date: Wed, 17 Jul 2019 10:02:05 -0700 -Subject: [PATCH] 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. -(cherry picked from commit a4a994bd3e619cbaff97610a1cee8ffa87c672f5) - -Co-authored-by: Abhilash Raj ---- - Lib/email/_header_value_parser.py | 3 +++ - Lib/test/test_email/test__header_value_parser.py | 7 +++++++ - .../next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst | 2 ++ - 3 files changed, 12 insertions(+) - create mode 100644 Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst - ---- a/Lib/email/_header_value_parser.py -+++ b/Lib/email/_header_value_parser.py -@@ -2387,6 +2387,9 @@ def get_parameter(value): - while value: - if value[0] in WSP: - token, value = get_fws(value) -+ elif value[0] == '"': -+ token = ValueTerminal('"', 'DQUOTE') -+ value = value[1:] - else: - token, value = get_qcontent(value) - v.append(token) ---- a/Lib/test/test_email/test__header_value_parser.py -+++ b/Lib/test/test_email/test__header_value_parser.py -@@ -2621,6 +2621,13 @@ class Test_parse_mime_parameters(TestPar - # Defects are apparent missing *0*, and two 'out of sequence'. - [errors.InvalidHeaderDefect]*3), - -+ # bpo-37461: Check that we don't go into an infinite loop. -+ 'extra_dquote': ( -+ 'r*="\'a\'\\"', -+ ' r="\\""', -+ 'r*=\'a\'"', -+ [('r', '"')], -+ [errors.InvalidHeaderDefect]*2), - } - - @parameterize ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2019-07-16-08-11-00.bpo-37461.1Ahz7O.rst -@@ -0,0 +1,2 @@ -+Fix an inifite loop when parsing specially crafted email headers. Patch by -+Abhilash Raj. diff --git a/lang/python/python3/patches/026-3.7-bpo-37764-Fix-infinite-loop-when-parsing-unstruc.patch b/lang/python/python3/patches/026-3.7-bpo-37764-Fix-infinite-loop-when-parsing-unstruc.patch deleted file mode 100644 index 6903ac4e37..0000000000 --- a/lang/python/python3/patches/026-3.7-bpo-37764-Fix-infinite-loop-when-parsing-unstruc.patch +++ /dev/null @@ -1,167 +0,0 @@ -From ea21389dda401457198fb214aa2c981a45ed9528 Mon Sep 17 00:00:00 2001 -From: Ashwin Ramaswami -Date: Tue, 3 Sep 2019 09:42:53 -0700 -Subject: [PATCH] [3.7] bpo-37764: Fix infinite loop when parsing unstructured - email headers. (GH-15239) (GH-15654) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -…aders. (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 -(cherry picked from commit c5b242f87f31286ad38991bc3868cf4cfbf2b681) - -Co-authored-by: Ashwin Ramaswami - - - - - -https://bugs.python.org/issue37764 ---- - Lib/email/_header_value_parser.py | 19 ++++++++++++++--- - .../test_email/test__header_value_parser.py | 16 ++++++++++++++ - Lib/test/test_email/test_email.py | 21 +++++++++++++++++++ - Misc/ACKS | 1 + - .../2019-08-27-01-13-05.bpo-37764.qv67PQ.rst | 1 + - 5 files changed, 55 insertions(+), 3 deletions(-) - create mode 100644 Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.rst - ---- a/Lib/email/_header_value_parser.py -+++ b/Lib/email/_header_value_parser.py -@@ -931,6 +931,10 @@ class EWWhiteSpaceTerminal(WhiteSpaceTer - return '' - - -+class _InvalidEwError(errors.HeaderParseError): -+ """Invalid encoded word found while parsing headers.""" -+ -+ - # XXX these need to become classes and used as instances so - # that a program can't change them in a parse tree and screw - # up other parse trees. Maybe should have tests for that, too. -@@ -1035,7 +1039,10 @@ def get_encoded_word(value): - raise errors.HeaderParseError( - "expected encoded word but found {}".format(value)) - remstr = ''.join(remainder) -- if len(remstr) > 1 and remstr[0] in hexdigits and remstr[1] in hexdigits: -+ if (len(remstr) > 1 and -+ remstr[0] in hexdigits and -+ remstr[1] in hexdigits and -+ tok.count('?') < 2): - # The ? after the CTE was followed by an encoded word escape (=XX). - rest, *remainder = remstr.split('?=', 1) - tok = tok + '?=' + rest -@@ -1047,7 +1054,7 @@ def get_encoded_word(value): - try: - text, charset, lang, defects = _ew.decode('=?' + tok + '?=') - except ValueError: -- raise errors.HeaderParseError( -+ raise _InvalidEwError( - "encoded word format invalid: '{}'".format(ew.cte)) - ew.charset = charset - ew.lang = lang -@@ -1097,9 +1104,12 @@ def get_unstructured(value): - token, value = get_fws(value) - unstructured.append(token) - continue -+ valid_ew = True - if value.startswith('=?'): - try: - token, value = get_encoded_word(value) -+ except _InvalidEwError: -+ valid_ew = False - except errors.HeaderParseError: - # XXX: Need to figure out how to register defects when - # appropriate here. -@@ -1121,7 +1131,10 @@ def get_unstructured(value): - # Split in the middle of an atom if there is a rfc2047 encoded word - # which does not have WSP on both sides. The defect will be registered - # the next time through the loop. -- if rfc2047_matcher.search(tok): -+ # This needs to only be performed when the encoded word is valid; -+ # otherwise, performing it on an invalid encoded word can cause -+ # the parser to go in an infinite loop. -+ if valid_ew and rfc2047_matcher.search(tok): - tok, *remainder = value.partition('=?') - vtext = ValueTerminal(tok, 'vtext') - _validate_xtext(vtext) ---- a/Lib/test/test_email/test__header_value_parser.py -+++ b/Lib/test/test_email/test__header_value_parser.py -@@ -383,6 +383,22 @@ class TestParser(TestParserMixin, TestEm - [errors.InvalidHeaderDefect], - '') - -+ def test_get_unstructured_without_trailing_whitespace_hang_case(self): -+ self._test_get_x(self._get_unst, -+ '=?utf-8?q?somevalue?=aa', -+ 'somevalueaa', -+ 'somevalueaa', -+ [errors.InvalidHeaderDefect], -+ '') -+ -+ def test_get_unstructured_invalid_ew(self): -+ self._test_get_x(self._get_unst, -+ '=?utf-8?q?=somevalue?=', -+ '=?utf-8?q?=somevalue?=', -+ '=?utf-8?q?=somevalue?=', -+ [], -+ '') -+ - # get_qp_ctext - - def test_get_qp_ctext_only(self): ---- a/Lib/test/test_email/test_email.py -+++ b/Lib/test/test_email/test_email.py -@@ -5367,6 +5367,27 @@ Content-Type: application/x-foo; - eq(language, 'en-us') - eq(s, 'My Document For You') - -+ def test_should_not_hang_on_invalid_ew_messages(self): -+ messages = ["""From: user@host.com -+To: user@host.com -+Bad-Header: -+ =?us-ascii?Q?LCSwrV11+IB0rSbSker+M9vWR7wEDSuGqmHD89Gt=ea0nJFSaiz4vX3XMJPT4vrE?= -+ =?us-ascii?Q?xGUZeOnp0o22pLBB7CYLH74Js=wOlK6Tfru2U47qR?= -+ =?us-ascii?Q?72OfyEY2p2=2FrA9xNFyvH+fBTCmazxwzF8nGkK6D?= -+ -+Hello! -+""", """From: ����� �������� -+To: "xxx" -+Subject: ��� ���������� ����� ����� � ��������� �� ���� -+MIME-Version: 1.0 -+Content-Type: text/plain; charset="windows-1251"; -+Content-Transfer-Encoding: 8bit -+ -+�� ����� � ���� ������ ��� �������� -+"""] -+ for m in messages: -+ with self.subTest(m=m): -+ msg = email.message_from_string(m) - - - # Tests to ensure that signed parts of an email are completely preserved, as ---- a/Misc/ACKS -+++ b/Misc/ACKS -@@ -1305,6 +1305,7 @@ Burton Radons - Abhilash Raj - Shorya Raj - Dhushyanth Ramasamy -+Ashwin Ramaswami - Jeff Ramnani - Bayard Randel - Varpu Rantala ---- /dev/null -+++ b/Misc/NEWS.d/next/Security/2019-08-27-01-13-05.bpo-37764.qv67PQ.rst -@@ -0,0 +1 @@ -+Fixes email._header_value_parser.get_unstructured going into an infinite loop for a specific case in which the email header does not have trailing whitespace, and the case in which it contains an invalid encoded word. Patch by Ashwin Ramaswami. -\ No newline at end of file diff --git a/lang/python/python3/patches/026-bpo-38243-xmlrpc.server-Escape-the-server_title-GH-1.patch b/lang/python/python3/patches/026-bpo-38243-xmlrpc.server-Escape-the-server_title-GH-1.patch new file mode 100644 index 0000000000..b79f81bd32 --- /dev/null +++ b/lang/python/python3/patches/026-bpo-38243-xmlrpc.server-Escape-the-server_title-GH-1.patch @@ -0,0 +1,83 @@ +From 1698cacfb924d1df452e78d11a4bf81ae7777389 Mon Sep 17 00:00:00 2001 +From: Victor Stinner +Date: Sat, 28 Sep 2019 09:33:00 +0200 +Subject: [PATCH] bpo-38243, xmlrpc.server: Escape the server_title (GH-16373) + (GH-16441) + +Escape the server title of xmlrpc.server.DocXMLRPCServer +when rendering the document page as HTML. + +(cherry picked from commit e8650a4f8c7fb76f570d4ca9c1fbe44e91c8dfaa) +--- + Lib/test/test_docxmlrpc.py | 16 ++++++++++++++++ + Lib/xmlrpc/server.py | 3 ++- + .../2019-09-25-13-21-09.bpo-38243.1pfz24.rst | 3 +++ + 3 files changed, 21 insertions(+), 1 deletion(-) + create mode 100644 Misc/NEWS.d/next/Security/2019-09-25-13-21-09.bpo-38243.1pfz24.rst + +diff --git a/Lib/test/test_docxmlrpc.py b/Lib/test/test_docxmlrpc.py +index 00903337c0..d2adb21af0 100644 +--- a/Lib/test/test_docxmlrpc.py ++++ b/Lib/test/test_docxmlrpc.py +@@ -1,5 +1,6 @@ + from xmlrpc.server import DocXMLRPCServer + import http.client ++import re + import sys + from test import support + threading = support.import_module('threading') +@@ -193,6 +194,21 @@ class DocXMLRPCHTTPGETServer(unittest.TestCase): + b'method_annotation(x: bytes)'), + response.read()) + ++ def test_server_title_escape(self): ++ # bpo-38243: Ensure that the server title and documentation ++ # are escaped for HTML. ++ self.serv.set_server_title('test_title