From 66cfcb96fba2f165c751c7853e4b7d81500c3940 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 18 2016 14:47:42 +0000 Subject: import rh-python34-python-3.4.2-13.el7 --- diff --git a/SOURCES/00237-CVE-2016-0772-smtplib.patch b/SOURCES/00237-CVE-2016-0772-smtplib.patch new file mode 100644 index 0000000..d3213bd --- /dev/null +++ b/SOURCES/00237-CVE-2016-0772-smtplib.patch @@ -0,0 +1,34 @@ +From 5b67aca6fb4246e84981d6361ba218bd52e73ac2 Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Tue, 21 Jun 2016 15:52:03 +0200 +Subject: [PATCH] Raise an error when STARTTLS fails + +CVE-2016-0772 python: smtplib StartTLS stripping attack +rhbz#1303647: https://bugzilla.redhat.com/show_bug.cgi?id=1303647 + +Based on an upstream change by Benjamin Peterson +- in changeset 101887:d590114c2394 3.4 +- https://hg.python.org/cpython/rev/d590114c2394 +--- + Lib/smtplib.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/Lib/smtplib.py b/Lib/smtplib.py +index dc16ef6..8bc806b 100755 +--- a/Lib/smtplib.py ++++ b/Lib/smtplib.py +@@ -655,6 +655,11 @@ class SMTP: + self.ehlo_resp = None + self.esmtp_features = {} + self.does_esmtp = 0 ++ else: ++ # RFC 3207: ++ # 501 Syntax error (no parameters allowed) ++ # 454 TLS not available due to temporary reason ++ raise SMTPResponseException(resp, reply) + return (resp, reply) + + def sendmail(self, from_addr, to_addrs, msg, mail_options=[], +-- +2.5.5 + diff --git a/SOURCES/00238-CVE-2016-5699-http-client.patch b/SOURCES/00238-CVE-2016-5699-http-client.patch new file mode 100644 index 0000000..897bc38 --- /dev/null +++ b/SOURCES/00238-CVE-2016-5699-http-client.patch @@ -0,0 +1,162 @@ +From bbb84befef00f8f57ada391a14587575e13750e7 Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Fri, 8 Jul 2016 10:56:25 +0200 +Subject: [PATCH] Disabled HTTP header injections in http.client. + +CVE-2016-5699 python: http protocol steam injection attack +rhbz#1303699 : https://bugzilla.redhat.com/show_bug.cgi?id=1303699 + +Based on an upstream change by Demian Brecht and Serhiy Storchaka +- in changeset 94952:bf3e1c9b80e9 3.4 +- https://hg.python.org/cpython/rev/bf3e1c9b80e9 +--- + Lib/http/client.py | 37 +++++++++++++++++++++++++++++++ + Lib/test/test_httplib.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 94 insertions(+) + +diff --git a/Lib/http/client.py b/Lib/http/client.py +index b4cdec4..d3ea7fa 100644 +--- a/Lib/http/client.py ++++ b/Lib/http/client.py +@@ -70,6 +70,7 @@ import email.parser + import email.message + import io + import os ++import re + import socket + import collections + from urllib.parse import urlsplit +@@ -215,6 +216,34 @@ MAXAMOUNT = 1048576 + _MAXLINE = 65536 + _MAXHEADERS = 100 + ++# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2) ++# ++# VCHAR = %x21-7E ++# obs-text = %x80-FF ++# header-field = field-name ":" OWS field-value OWS ++# field-name = token ++# field-value = *( field-content / obs-fold ) ++# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] ++# field-vchar = VCHAR / obs-text ++# ++# obs-fold = CRLF 1*( SP / HTAB ) ++# ; obsolete line folding ++# ; see Section 3.2.4 ++ ++# token = 1*tchar ++# ++# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" ++# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" ++# / DIGIT / ALPHA ++# ; any VCHAR, except delimiters ++# ++# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1 ++ ++# the patterns for both name and value are more leniant than RFC ++# definitions to allow for backwards compatibility ++_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch ++_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search ++ + + class HTTPMessage(email.message.Message): + # XXX The only usage of this method is in +@@ -1060,12 +1089,20 @@ class HTTPConnection: + + if hasattr(header, 'encode'): + header = header.encode('ascii') ++ ++ if not _is_legal_header_name(header): ++ raise ValueError('Invalid header name %r' % (header,)) ++ + values = list(values) + for i, one_value in enumerate(values): + if hasattr(one_value, 'encode'): + values[i] = one_value.encode('latin-1') + elif isinstance(one_value, int): + values[i] = str(one_value).encode('ascii') ++ ++ if _is_illegal_header_value(values[i]): ++ raise ValueError('Invalid header value %r' % (values[i],)) ++ + value = b'\r\n\t'.join(values) + header = header + b': ' + value + self._output(header) +diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py +index 2ded60e..e795287 100644 +--- a/Lib/test/test_httplib.py ++++ b/Lib/test/test_httplib.py +@@ -141,6 +141,33 @@ class HeaderTests(TestCase): + conn.putheader('Content-length', 42) + self.assertIn(b'Content-length: 42', conn._buffer) + ++ conn.putheader('Foo', ' bar ') ++ self.assertIn(b'Foo: bar ', conn._buffer) ++ conn.putheader('Bar', '\tbaz\t') ++ self.assertIn(b'Bar: \tbaz\t', conn._buffer) ++ conn.putheader('Authorization', 'Bearer mytoken') ++ self.assertIn(b'Authorization: Bearer mytoken', conn._buffer) ++ conn.putheader('IterHeader', 'IterA', 'IterB') ++ self.assertIn(b'IterHeader: IterA\r\n\tIterB', conn._buffer) ++ conn.putheader('LatinHeader', b'\xFF') ++ self.assertIn(b'LatinHeader: \xFF', conn._buffer) ++ conn.putheader('Utf8Header', b'\xc3\x80') ++ self.assertIn(b'Utf8Header: \xc3\x80', conn._buffer) ++ conn.putheader('C1-Control', b'next\x85line') ++ self.assertIn(b'C1-Control: next\x85line', conn._buffer) ++ conn.putheader('Embedded-Fold-Space', 'is\r\n allowed') ++ self.assertIn(b'Embedded-Fold-Space: is\r\n allowed', conn._buffer) ++ conn.putheader('Embedded-Fold-Tab', 'is\r\n\tallowed') ++ self.assertIn(b'Embedded-Fold-Tab: is\r\n\tallowed', conn._buffer) ++ conn.putheader('Key Space', 'value') ++ self.assertIn(b'Key Space: value', conn._buffer) ++ conn.putheader('KeySpace ', 'value') ++ self.assertIn(b'KeySpace : value', conn._buffer) ++ conn.putheader(b'Nonbreak\xa0Space', 'value') ++ self.assertIn(b'Nonbreak\xa0Space: value', conn._buffer) ++ conn.putheader(b'\xa0NonbreakSpace', 'value') ++ self.assertIn(b'\xa0NonbreakSpace: value', conn._buffer) ++ + def test_ipv6host_header(self): + # Default host header on IPv6 transaction should wrapped by [] if + # its actual IPv6 address +@@ -160,6 +187,36 @@ class HeaderTests(TestCase): + conn.request('GET', '/foo') + self.assertTrue(sock.data.startswith(expected)) + ++ def test_invalid_headers(self): ++ conn = client.HTTPConnection('example.com') ++ conn.sock = FakeSocket('') ++ conn.putrequest('GET', '/') ++ ++ # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no ++ # longer allowed in header names ++ cases = ( ++ (b'Invalid\r\nName', b'ValidValue'), ++ (b'Invalid\rName', b'ValidValue'), ++ (b'Invalid\nName', b'ValidValue'), ++ (b'\r\nInvalidName', b'ValidValue'), ++ (b'\rInvalidName', b'ValidValue'), ++ (b'\nInvalidName', b'ValidValue'), ++ (b' InvalidName', b'ValidValue'), ++ (b'\tInvalidName', b'ValidValue'), ++ (b'Invalid:Name', b'ValidValue'), ++ (b':InvalidName', b'ValidValue'), ++ (b'ValidName', b'Invalid\r\nValue'), ++ (b'ValidName', b'Invalid\rValue'), ++ (b'ValidName', b'Invalid\nValue'), ++ (b'ValidName', b'InvalidValue\r\n'), ++ (b'ValidName', b'InvalidValue\r'), ++ (b'ValidName', b'InvalidValue\n'), ++ ) ++ for name, value in cases: ++ with self.subTest((name, value)): ++ with self.assertRaisesRegex(ValueError, 'Invalid header'): ++ conn.putheader(name, value) ++ + + class BasicTest(TestCase): + def test_status_lines(self): +-- +2.9.0 + diff --git a/SOURCES/00239-Replace-512-bit-dh-key-with-a-1024-bit-one.patch b/SOURCES/00239-Replace-512-bit-dh-key-with-a-1024-bit-one.patch new file mode 100644 index 0000000..58cf653 --- /dev/null +++ b/SOURCES/00239-Replace-512-bit-dh-key-with-a-1024-bit-one.patch @@ -0,0 +1,65 @@ +From fbed024f6a7fb631065fdc34bd5f7de8a024661e Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Wed, 29 Jun 2016 17:41:46 +0200 +Subject: [PATCH] Replace 512 bit dh key with a 1024 bit one +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Python upstream issue 24985: https://bugs.python.org/issue24985 +- python SSL test fails due to minimum key size being increased in OpenSSL + +Based on an upstream change by Cédric Krier: +- https://hg.python.org/cpython/rev/1ad7c0253abe +--- + Lib/test/dh1024.pem | 7 +++++++ + Lib/test/dh512.pem | 9 --------- + Lib/test/test_ssl.py | 2 +- + 3 files changed, 8 insertions(+), 10 deletions(-) + create mode 100644 Lib/test/dh1024.pem + delete mode 100644 Lib/test/dh512.pem + +diff --git a/Lib/test/dh1024.pem b/Lib/test/dh1024.pem +new file mode 100644 +index 0000000..a391176 +--- /dev/null ++++ b/Lib/test/dh1024.pem +@@ -0,0 +1,7 @@ ++-----BEGIN DH PARAMETERS----- ++MIGHAoGBAIbzw1s9CT8SV5yv6L7esdAdZYZjPi3qWFs61CYTFFQnf2s/d09NYaJt ++rrvJhIzWavqnue71qXCf83/J3nz3FEwUU/L0mGyheVbsSHiI64wUo3u50wK5Igo0 ++RNs/LD0irs7m0icZ//hijafTU+JOBiuA8zMI+oZfU7BGuc9XrUprAgEC ++-----END DH PARAMETERS----- ++ ++Generated with: openssl dhparam -out dh1024.pem 1024 +diff --git a/Lib/test/dh512.pem b/Lib/test/dh512.pem +deleted file mode 100644 +index 200d16c..0000000 +--- a/Lib/test/dh512.pem ++++ /dev/null +@@ -1,9 +0,0 @@ +------BEGIN DH PARAMETERS----- +-MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak +-XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC +------END DH PARAMETERS----- +- +-These are the 512 bit DH parameters from "Assigned Number for SKIP Protocols" +-(http://www.skip-vpn.org/spec/numbers.html). +-See there for how they were generated. +-Note that g is not a generator, but this is not a problem since p is a safe prime. +diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py +index 7febab3..1192708 100644 +--- a/Lib/test/test_ssl.py ++++ b/Lib/test/test_ssl.py +@@ -65,7 +65,7 @@ BADKEY = data_file("badkey.pem") + NOKIACERT = data_file("nokia.pem") + NULLBYTECERT = data_file("nullbytecert.pem") + +-DHFILE = data_file("dh512.pem") ++DHFILE = data_file("dh1024.pem") + BYTES_DHFILE = os.fsencode(DHFILE) + + +-- +2.9.0 + diff --git a/SOURCES/00242-CVE-2016-1000110-httpoxy.patch b/SOURCES/00242-CVE-2016-1000110-httpoxy.patch new file mode 100644 index 0000000..908e227 --- /dev/null +++ b/SOURCES/00242-CVE-2016-1000110-httpoxy.patch @@ -0,0 +1,98 @@ + +# HG changeset patch +# User Senthil Kumaran +# Date 1469946256 25200 +# Node ID 95b09ccc8a3eda0a1c9e61b366e31be443f7a34c +# Parent 1c06e02b968a1645ebaa282fd2c40f6356792251 +Prevent HTTPoxy attack (CVE-2016-1000110) + +Ignore the HTTP_PROXY variable when REQUEST_METHOD environment is set, which +indicates that the script is in CGI mode. + +Issue #27568 Reported and patch contributed by Rémi Rampin. + +diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst +--- a/Doc/howto/urllib2.rst ++++ b/Doc/howto/urllib2.rst +@@ -538,6 +538,11 @@ setting up a `Basic Authentication`_ han + through a proxy. However, this can be enabled by extending urllib.request as + shown in the recipe [#]_. + ++.. note:: ++ ++ `HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; see ++ the documentation on :func:`~urllib.request.getproxies`. ++ + + Sockets and Layers + ================== +diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst +--- a/Doc/library/urllib.request.rst ++++ b/Doc/library/urllib.request.rst +@@ -161,6 +161,14 @@ The :mod:`urllib.request` module defines + cannot find it, looks for proxy information from Mac OSX System + Configuration for Mac OS X and Windows Systems Registry for Windows. + ++ .. note:: ++ ++ If the environment variable ``REQUEST_METHOD`` is set, which usually ++ indicates your script is running in a CGI environment, the environment ++ variable ``HTTP_PROXY`` (uppercase ``_PROXY``) will be ignored. This is ++ because that variable can be injected by a client using the "Proxy:" HTTP ++ header. If you need to use an HTTP proxy in a CGI environment use ++ ``ProxyHandler`` explicitly. + + The following classes are provided: + +@@ -265,6 +273,11 @@ The following classes are provided: + + To disable autodetected proxy pass an empty dictionary. + ++ .. note:: ++ ++ ``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; ++ see the documentation on :func:`~urllib.request.getproxies`. ++ + + .. class:: HTTPPasswordMgr() + +diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py +--- a/Lib/test/test_urllib.py ++++ b/Lib/test/test_urllib.py +@@ -222,6 +222,19 @@ class ProxyTests(unittest.TestCase): + self.env.set('NO_PROXY', 'localhost, anotherdomain.com, newdomain.com') + self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com')) + ++ def test_proxy_cgi_ignore(self): ++ try: ++ self.env.set('HTTP_PROXY', 'http://somewhere:3128') ++ proxies = urllib.request.getproxies_environment() ++ self.assertEqual('http://somewhere:3128', proxies['http']) ++ self.env.set('REQUEST_METHOD', 'GET') ++ proxies = urllib.request.getproxies_environment() ++ self.assertNotIn('http', proxies) ++ finally: ++ self.env.unset('REQUEST_METHOD') ++ self.env.unset('HTTP_PROXY') ++ ++ + class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin): + """Test urlopen() opening a fake http connection.""" + +diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py +--- a/Lib/urllib/request.py ++++ b/Lib/urllib/request.py +@@ -2366,6 +2366,13 @@ def getproxies_environment(): + name = name.lower() + if value and name[-6:] == '_proxy': + proxies[name[:-6]] = value ++ ++ # CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY ++ # (non-all-lowercase) as it may be set from the web server by a "Proxy:" ++ # header from the client ++ if 'REQUEST_METHOD' in os.environ: ++ proxies.pop('http', None) ++ + return proxies + + def proxy_bypass_environment(host): diff --git a/SPECS/python.spec b/SPECS/python.spec index 0e60a77..b9850ec 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -146,7 +146,7 @@ Summary: Version 3 of the Python programming language aka Python 3000 Name: %{?scl_prefix}python Version: %{pybasever}.2 -Release: 9%{?dist} +Release: 13%{?dist} License: Python Group: Development/Languages @@ -718,6 +718,39 @@ Patch202:00202-enable-cert-verify-by-default.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1203236 Patch203: 00203-tempfile-shouldnt-close-if-used-as-iterator.patch +# 00237 # +# CVE-2016-0772 python: smtplib StartTLS stripping attack +# https://bugzilla.redhat.com/show_bug.cgi?id=1303647 +# FIXED UPSTREAM: https://hg.python.org/cpython/rev/d590114c2394 +# Raise an error when STARTTLS fails +# Resolves: rhbz#1346360 +Patch237: 00237-CVE-2016-0772-smtplib.patch + +# 00238 # +# CVE-2016-5699 python: http protocol steam injection attack +# https://bugzilla.redhat.com/show_bug.cgi?id=1303699 +# FIXED UPSTREAM: https://hg.python.org/cpython/rev/bf3e1c9b80e9 +# Disabled HTTP header injections in http.client +# Resolves: rhbz#1346360 +Patch238: 00238-CVE-2016-5699-http-client.patch + +# 00239 # +# Python upstream issue #24985: https://bugs.python.org/issue24985 +# python SSL test fails due to minimum key size being increased in OpenSSL +# FIXED UPSTREAM: https://hg.python.org/cpython/rev/1ad7c0253abe +# Replace 512 bit dh key with a 1024 bit one +# Resolves: rhbz#1356506 +Patch239: 00239-Replace-512-bit-dh-key-with-a-1024-bit-one.patch + +# 00242 # +# HTTPoxy attack (CVE-2016-1000110) +# https://httpoxy.org/ +# FIXED UPSTREAM: http://bugs.python.org/issue27568 +# Based on a patch by Rémi Rampin +# Resolves: rhbz#1359171 +Patch242: 00242-CVE-2016-1000110-httpoxy.patch + + Patch300: 00300-change-so-version-scl.patch @@ -1008,6 +1041,11 @@ done %patch201 -p1 %patch202 -p1 %patch203 -p1 +%patch237 -p1 +%patch238 -p1 +%patch239 -p1 +%patch242 -p1 + cat %{PATCH300} | sed -e "s/__SCL_NAME__/%{?scl}/" \ | patch -p1 @@ -1980,6 +2018,26 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Fri Aug 05 2016 Charalampos Stratakis - 3.4.2-13 +- Fix for CVE-2016-1000110 HTTPoxy attack +Resolves: rhbz#1359171 + +* Thu Jul 14 2016 Tomas Orsava - 3.4.2-12 +- Replace 512 bit dh key with a 1024 bit one (upstream change) +- Python upstream issue #24985: https://bugs.python.org/issue24985 + python SSL test fails due to minimum key size being increased in OpenSSL +Resolves: rhbz#1356506 + +* Fri Jul 08 2016 Tomas Orsava - 3.4.2-11 +- Fix for CVE-2016-5699 python: http protocol steam injection attack (rhbz#1303699) + Disabled HTTP header injections in http.client (upstream patch) +Resolves: rhbz#1346360 + +* Tue Jun 21 2016 Tomas Orsava - 3.4.2-10 +- Fix for CVE-2016-0772 python: smtplib StartTLS stripping attack (rhbz#1303647) + Raise an error when STARTTLS fails (upstream patch) +Resolves: rhbz#1346360 + * Tue Mar 24 2015 Slavek Kabrda - 3.4.2-9 - Build debug build with -O1 to improve GDB backtraces Resolves: rhbz#1204169