Hello community, here is the log from the commit of package python for openSUSE:Leap:15.2 checked in at 2020-05-26 18:32:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python (Old) and /work/SRC/openSUSE:Leap:15.2/.python.new.2738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python" Tue May 26 18:32:07 2020 rev:52 rq:808115 version:2.7.17 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python/python-base.changes 2020-03-01 08:50:59.721228071 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python.new.2738/python-base.changes 2020-05-26 18:32:08.405544303 +0200 @@ -1,0 +2,9 @@ +Fri May 1 15:52:49 UTC 2020 - Matej Cepl <[email protected]> + +- Add CVE-2019-18348-CRLF_injection_via_host_part.patch to + disallow control characters in hostnames in httplib, + addressing CVE-2019-18348. Such potentially malicious header + injection URLs now cause a InvalidURL to be raised. + (bsc#1155094) + +------------------------------------------------------------------- --- /work/SRC/openSUSE:Leap:15.2/python/python-doc.changes 2020-03-01 08:50:59.793228214 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python.new.2738/python-doc.changes 2020-05-26 18:32:09.361546392 +0200 @@ -1,0 +2,16 @@ +Fri May 1 15:52:49 UTC 2020 - Matej Cepl <[email protected]> + +- Add CVE-2019-18348-CRLF_injection_via_host_part.patch to + disallow control characters in hostnames in httplib, + addressing CVE-2019-18348. Such potentially malicious header + injection URLs now cause a InvalidURL to be raised. + (bsc#1155094) + +------------------------------------------------------------------- +Sat Feb 8 23:29:28 CET 2020 - Matej Cepl <[email protected]> + +- Add CVE-2019-9674-zip-bomb.patch to improve documentation + warning about dangers of zip-bombs and other security problems + with zipfile library. (bsc#1162825 CVE-2019-9674) + +------------------------------------------------------------------- python.changes: same change New: ---- CVE-2019-18348-CRLF_injection_via_host_part.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-base.spec ++++++ --- /var/tmp/diff_new_pack.tO57Bm/_old 2020-05-26 18:32:12.545553346 +0200 +++ /var/tmp/diff_new_pack.tO57Bm/_new 2020-05-26 18:32:12.545553346 +0200 @@ -94,6 +94,9 @@ # PATCH-FIX-UPSTREAM CVE-2019-9674-zip-bomb.patch bsc#1162825 [email protected] # Improve documentation warning against the possible zip bombs Patch59: CVE-2019-9674-zip-bomb.patch +# PATCH-FIX-UPSTREAM CVE-2019-18348-CRLF_injection_via_host_part.patch bsc#1155094 [email protected] +# disallow control characters in hostnames in httplib +Patch60: CVE-2019-18348-CRLF_injection_via_host_part.patch # COMMON-PATCH-END %define python_version %(echo %{tarversion} | head -c 3) BuildRequires: automake @@ -219,6 +222,7 @@ %patch56 -p1 %patch58 -p1 %patch59 -p1 +%patch60 -p1 # drop Autoconf version requirement sed -i 's/^version_required/dnl version_required/' configure.ac ++++++ python-doc.spec ++++++ --- /var/tmp/diff_new_pack.tO57Bm/_old 2020-05-26 18:32:12.565553390 +0200 +++ /var/tmp/diff_new_pack.tO57Bm/_new 2020-05-26 18:32:12.569553398 +0200 @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # - Name: python-doc Version: 2.7.17 Release: 0 @@ -92,6 +91,9 @@ # PATCH-FIX-UPSTREAM CVE-2019-9674-zip-bomb.patch bsc#1162825 [email protected] # Improve documentation warning against the possible zip bombs Patch59: CVE-2019-9674-zip-bomb.patch +# PATCH-FIX-UPSTREAM CVE-2019-18348-CRLF_injection_via_host_part.patch bsc#1155094 [email protected] +# disallow control characters in hostnames in httplib +Patch60: CVE-2019-18348-CRLF_injection_via_host_part.patch # COMMON-PATCH-END Provides: pyth_doc Provides: pyth_ps @@ -158,6 +160,7 @@ %patch56 -p1 %patch58 -p1 %patch59 -p1 +%patch60 -p1 # drop Autoconf version requirement sed -i 's/^version_required/dnl version_required/' configure.ac ++++++ python.spec ++++++ --- /var/tmp/diff_new_pack.tO57Bm/_old 2020-05-26 18:32:12.589553443 +0200 +++ /var/tmp/diff_new_pack.tO57Bm/_new 2020-05-26 18:32:12.593553451 +0200 @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via https://bugs.opensuse.org/ # - Name: python Version: 2.7.17 Release: 0 @@ -96,6 +95,9 @@ # PATCH-FIX-UPSTREAM CVE-2019-9674-zip-bomb.patch bsc#1162825 [email protected] # Improve documentation warning against the possible zip bombs Patch59: CVE-2019-9674-zip-bomb.patch +# PATCH-FIX-UPSTREAM CVE-2019-18348-CRLF_injection_via_host_part.patch bsc#1155094 [email protected] +# disallow control characters in hostnames in httplib +Patch60: CVE-2019-18348-CRLF_injection_via_host_part.patch # COMMON-PATCH-END BuildRequires: automake BuildRequires: db-devel @@ -276,6 +278,7 @@ %patch56 -p1 %patch58 -p1 %patch59 -p1 +%patch60 -p1 # drop Autoconf version requirement sed -i 's/^version_required/dnl version_required/' configure.ac ++++++ CVE-2019-18348-CRLF_injection_via_host_part.patch ++++++ --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -745,6 +745,8 @@ class HTTPConnection: (self.host, self.port) = self._get_hostport(host, port) + self._validate_host(self.host) + # This is stored as an instance variable to allow unittests # to replace with a suitable mock self._create_connection = socket.create_connection @@ -1029,6 +1031,17 @@ class HTTPConnection: ).format(matched=match.group(), url=url) raise InvalidURL(msg) + def _validate_host(self, host): + """Validate a host so it doesn't contain control characters.""" + # Prevent CVE-2019-18348. + match = _contains_disallowed_url_pchar_re.search(host) + if match: + msg = ( + "URL can't contain control characters. {host!r} " + "(found at least {matched!r})" + ).format(matched=match.group(), host=host) + raise InvalidURL(msg) + def putheader(self, header, *values): """Send a request header line to the server. --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -702,7 +702,7 @@ class BasicTest(TestCase): with self.assertRaisesRegexp(socket.error, "Invalid response"): conn._tunnel() - def test_putrequest_override_validation(self): + def test_putrequest_override_domain_validation(self): """ It should be possible to override the default validation behavior in putrequest (bpo-38216). @@ -715,6 +715,17 @@ class BasicTest(TestCase): conn.sock = FakeSocket('') conn.putrequest('GET', '/\x00') + def test_putrequest_override_host_validation(self): + class UnsafeHTTPConnection(httplib.HTTPConnection): + def _validate_host(self, url): + pass + + conn = UnsafeHTTPConnection('example.com\r\n') + conn.sock = FakeSocket('') + # set skip_host so a ValueError is not raised upon adding the + # invalid URL as the value of the "Host:" header + conn.putrequest('GET', '/', skip_host=1) + class OfflineTest(TestCase): def test_responses(self): --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1321,7 +1321,7 @@ class MiscTests(unittest.TestCase, FakeH ) @unittest.skipUnless(ssl, "ssl module required") - def test_url_with_control_char_rejected(self): + def test_url_path_with_control_char_rejected(self): for char_no in range(0, 0x21) + range(0x7f, 0x100): char = chr(char_no) schemeless_url = "//localhost:7777/test%s/" % char @@ -1345,7 +1345,7 @@ class MiscTests(unittest.TestCase, FakeH self.unfakehttp() @unittest.skipUnless(ssl, "ssl module required") - def test_url_with_newline_header_injection_rejected(self): + def test_url_path_with_newline_header_injection_rejected(self): self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123" schemeless_url = "//" + host + ":8080/test/?test=a" @@ -1357,14 +1357,32 @@ class MiscTests(unittest.TestCase, FakeH # calls urllib.parse.quote() on the URL which makes all of the # above attempts at injection within the url _path_ safe. InvalidURL = httplib.InvalidURL - with self.assertRaisesRegexp( - InvalidURL, r"contain control.*\\r.*(found at least . .)"): - urllib2.urlopen("http:" + schemeless_url) - with self.assertRaisesRegexp(InvalidURL, r"contain control.*\\n"): - urllib2.urlopen("https:" + schemeless_url) + with self.assertRaisesRegexp(InvalidURL, + r"contain control.*\\r.*(found at least . .)"): + urllib2.urlopen("http:{}".format(schemeless_url)) + with self.assertRaisesRegexp(InvalidURL, + r"contain control.*\\n"): + urllib2.urlopen("https:{}".format(schemeless_url)) finally: self.unfakehttp() + @unittest.skipUnless(ssl, "ssl module required") + def test_url_host_with_control_char_rejected(self): + for char_no in list(range(0, 0x21)) + [0x7f]: + char = chr(char_no) + schemeless_url = "//localhost{}/test/".format(char) + self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.") + try: + escaped_char_repr = repr(char).replace('\\', r'\\') + InvalidURL = httplib.InvalidURL + with self.assertRaisesRegexp(InvalidURL, + "contain control.*{}".format(escaped_char_repr)): + urllib2.urlopen("http:{}".format(schemeless_url)) + with self.assertRaisesRegexp(InvalidURL, + "contain control.*{}".format(escaped_char_repr)): + urllib2.urlopen("https:{}".format(schemeless_url)) + finally: + self.unfakehttp() class RequestTests(unittest.TestCase):
