diff -Nru python-urllib3-1.22/debian/changelog python-urllib3-1.22/debian/changelog --- python-urllib3-1.22/debian/changelog 2018-01-04 14:09:14.000000000 +0000 +++ python-urllib3-1.22/debian/changelog 2019-05-13 18:27:58.000000000 +0000 @@ -1,3 +1,28 @@ +python-urllib3 (1.22-1ubuntu0.18.10.1) cosmic-security; urgency=medium + + * SECURITY UPDATE: credential disclosure via cross-origin redirect + - debian/patches/CVE-2018-20060-*.patch: backport logic to strip + Authorization header when following a cross-origin redirect. + - CVE-2018-20060 + * SECURITY UPDATE: CRLF injection issue + - debian/patches/CVE-2019-11236-1.patch: check for control chars in URL + in urllib3/connection.py, urllib3/connectionpool.py, + urllib3/contrib/pyopenssl.py, urllib3/contrib/socks.py, + urllib3/util/url.py, test/test_util.py. + - debian/patches/CVE-2019-11236-2.patch: percent-encode invalid target + characters in urllib3/util/url.py, test/test_util.py. + - debian/patches/CVE-2019-11236-3.patch: don't use embedded python-six + in urllib3/util/url.py. + - CVE-2019-11236 + * SECURITY UPDATE: CA cert mishandling + - debian/patches/CVE-2019-11324.patch: don't load system certificates + by default when any other CA cert parameters are specified in + urllib3/util/ssl_.py. + - CVE-2019-11324 + * debian/patches/fix_cert_error.patch: fix failing test. + + -- Marc Deslauriers Mon, 13 May 2019 14:27:58 -0400 + python-urllib3 (1.22-1) unstable; urgency=medium * Team upload. diff -Nru python-urllib3-1.22/debian/control python-urllib3-1.22/debian/control --- python-urllib3-1.22/debian/control 2018-01-04 13:58:38.000000000 +0000 +++ python-urllib3-1.22/debian/control 2019-05-13 18:27:58.000000000 +0000 @@ -1,5 +1,6 @@ Source: python-urllib3 -Maintainer: Debian Python Modules Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Python Modules Team Uploaders: Daniele Tricoli Section: python Priority: optional diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-10.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-10.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-10.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-10.patch 2019-05-13 18:27:58.000000000 +0000 @@ -0,0 +1,41 @@ +From 2a42e70ff077006d5a6da92251ddbb2939303f94 Mon Sep 17 00:00:00 2001 +From: "Seth M. Larson" +Date: Tue, 27 Mar 2018 14:44:51 -0500 +Subject: [PATCH] Move DEFAULT_REDIRECT_HEADERS_BLACKLIST under Retry + +--- + urllib3/util/retry.py | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/urllib3/util/retry.py b/urllib3/util/retry.py +index 37a3a74e9..948c15926 100644 +--- a/urllib3/util/retry.py ++++ b/urllib3/util/retry.py +@@ -20,9 +20,6 @@ + log = logging.getLogger(__name__) + + +-DEFAULT_REDIRECT_HEADERS_BLACKLIST = ['Authorization'] +- +- + # Data structure for representing the metadata of requests that result in a retry. + RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) +@@ -154,6 +151,8 @@ class Retry(object): + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + ++ DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) ++ + #: Maximum backoff time. + BACKOFF_MAX = 120 + +@@ -173,7 +172,7 @@ def __init__(self, total=10, connect=None, read=None, redirect=None, status=None + raise_on_redirect = False + + if remove_headers_on_redirect is None: +- remove_headers_on_redirect = DEFAULT_REDIRECT_HEADERS_BLACKLIST ++ remove_headers_on_redirect = self.DEFAULT_REDIRECT_HEADERS_BLACKLIST + remove_headers_on_redirect = set(remove_headers_on_redirect) + + self.redirect = redirect diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-12.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-12.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-12.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-12.patch 2019-05-13 18:17:28.000000000 +0000 @@ -0,0 +1,33 @@ +From 63948f3a607ed8e7a3ce9ac4e20782359896e27e Mon Sep 17 00:00:00 2001 +From: "Seth M. Larson" +Date: Wed, 28 Mar 2018 11:06:59 -0500 +Subject: [PATCH] Change remove_headers_on_redirect default value + +--- + urllib3/util/retry.py | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/urllib3/util/retry.py b/urllib3/util/retry.py +index 948c15926..7ad3dc660 100644 +--- a/urllib3/util/retry.py ++++ b/urllib3/util/retry.py +@@ -160,7 +160,7 @@ def __init__(self, total=10, connect=None, read=None, redirect=None, status=None + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True, +- remove_headers_on_redirect=None): ++ remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): + + self.total = total + self.connect = connect +@@ -171,10 +171,6 @@ def __init__(self, total=10, connect=None, read=None, redirect=None, status=None + redirect = 0 + raise_on_redirect = False + +- if remove_headers_on_redirect is None: +- remove_headers_on_redirect = self.DEFAULT_REDIRECT_HEADERS_BLACKLIST +- remove_headers_on_redirect = set(remove_headers_on_redirect) +- + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-1.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-1.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-1.patch 2019-05-13 18:16:32.000000000 +0000 @@ -0,0 +1,51 @@ +From 3d7f98b07b6e6e04c2e89cdf5afb18024a2d804c Mon Sep 17 00:00:00 2001 +From: SethMichaelLarson +Date: Sun, 25 Mar 2018 20:30:13 -0500 +Subject: [PATCH] Add forward_auth_headers_across_hosts parameter to Retry + +--- + urllib3/util/retry.py | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/urllib3/util/retry.py b/urllib3/util/retry.py +index c603cb490..c17620ab2 100644 +--- a/urllib3/util/retry.py ++++ b/urllib3/util/retry.py +@@ -139,6 +139,10 @@ class Retry(object): + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + ++ :param bool forward_auth_headers_across_hosts: ++ Whether to forward Authentication headers if a response is received ++ that redirects to a different host than the original request. ++ Defaults to False. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ +@@ -152,7 +156,8 @@ class Retry(object): + def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, +- history=None, respect_retry_after_header=True): ++ history=None, respect_retry_after_header=True, ++ forward_auth_headers_across_hosts=False): + + self.total = total + self.connect = connect +@@ -171,6 +176,8 @@ def __init__(self, total=10, connect=None, read=None, redirect=None, status=None + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header ++ self.forward_auth_headers_across_hosts = \ ++ forward_auth_headers_across_hosts + + def new(self, **kw): + params = dict( +@@ -182,6 +189,7 @@ def new(self, **kw): + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, ++ forward_auth_headers_across_hosts=self.forward_auth_headers_across_hosts + ) + params.update(kw) + return type(self)(**params) diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-2.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-2.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-2.patch 2019-05-13 18:16:43.000000000 +0000 @@ -0,0 +1,90 @@ +From f99912beeaf230ee3634b938d3ea426ffd1f3e57 Mon Sep 17 00:00:00 2001 +From: SethMichaelLarson +Date: Sun, 25 Mar 2018 20:30:47 -0500 +Subject: [PATCH] Add Authentication strip logic to ConnectionPool + +--- + test/with_dummyserver/test_connectionpool.py | 33 +++++++++++++++++++- + urllib3/connectionpool.py | 7 +++++ + 2 files changed, 39 insertions(+), 1 deletion(-) + +Index: python-urllib3-1.22/test/with_dummyserver/test_connectionpool.py +=================================================================== +--- python-urllib3-1.22.orig/test/with_dummyserver/test_connectionpool.py 2019-05-13 14:16:39.689660552 -0400 ++++ python-urllib3-1.22/test/with_dummyserver/test_connectionpool.py 2019-05-13 14:16:39.685660535 -0400 +@@ -5,11 +5,15 @@ import sys + import unittest + import time + import warnings ++import json + + import mock + + from .. import ( +- TARPIT_HOST, VALID_SOURCE_ADDRESSES, INVALID_SOURCE_ADDRESSES, ++ TARPIT_HOST, ++ VALID_SOURCE_ADDRESSES, ++ INVALID_SOURCE_ADDRESSES, ++ requires_network + ) + from ..port_helpers import find_unused_port + from urllib3 import ( +@@ -743,6 +747,8 @@ class TestRetry(HTTPDummyServerTestCase) + self.pool = HTTPConnectionPool(self.host, self.port) + self.addCleanup(self.pool.close) + ++ self.base_url_alt = 'http://%s:%d' % (self.host_alt, self.port) ++ + def test_max_retry(self): + try: + r = self.pool.request('GET', '/redirect', +@@ -861,6 +867,31 @@ class TestRetry(HTTPDummyServerTestCase) + actual = [(history.status, history.redirect_location) for history in r.retries.history] + self.assertEqual(actual, expected) + ++ def test_redirect_cross_host_no_forward_auth_headers(self): ++ url = '/redirect?target=%s/headers' % self.base_url_alt ++ headers = {'Authentication': 'foo'} ++ ++ resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False) ++ ++ self.assertEqual(resp.status, 200) ++ ++ data = json.loads(resp.data.decode('utf-8')) ++ ++ self.assertNotIn('Authentication', data) ++ ++ def test_redirect_cross_host_forward_auth_headers(self): ++ url = '/redirect?target=%s/headers' % self.base_url_alt ++ headers = {'Authentication': 'foo'} ++ retry = Retry(redirect=2, forward_auth_headers_across_hosts=True) ++ ++ resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False, retries=retry) ++ ++ self.assertEqual(resp.status, 200) ++ ++ data = json.loads(resp.data.decode('utf-8')) ++ ++ self.assertEqual(data['Authentication'], 'foo') ++ + + class TestRetryAfter(HTTPDummyServerTestCase): + def setUp(self): +Index: python-urllib3-1.22/urllib3/connectionpool.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/connectionpool.py 2019-05-13 14:16:39.689660552 -0400 ++++ python-urllib3-1.22/urllib3/connectionpool.py 2019-05-13 14:16:39.685660535 -0400 +@@ -695,6 +695,13 @@ class HTTPConnectionPool(ConnectionPool, + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + ++ # Strip the Authentication header if redirecting to a new host ++ # and we don't want to forward that header across hosts. ++ if (not retries.forward_auth_headers_across_hosts ++ and 'Authentication' in headers ++ and not self.is_same_host(redirect_location)): ++ headers.pop('Authentication') ++ + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-3.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-3.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-3.patch 2019-05-13 18:16:49.000000000 +0000 @@ -0,0 +1,89 @@ +From 48dba048081dfcb999afcda715d17147aa15b6ea Mon Sep 17 00:00:00 2001 +From: SethMichaelLarson +Date: Sun, 25 Mar 2018 20:31:10 -0500 +Subject: [PATCH] Add Authentication strip logic to PoolManager + +--- + test/with_dummyserver/test_poolmanager.py | 29 +++++++++++++++++++++++ + urllib3/poolmanager.py | 13 +++++++++- + 2 files changed, 41 insertions(+), 1 deletion(-) + +Index: python-urllib3-1.22/test/with_dummyserver/test_poolmanager.py +=================================================================== +--- python-urllib3-1.22.orig/test/with_dummyserver/test_poolmanager.py 2019-05-13 14:16:47.301691266 -0400 ++++ python-urllib3-1.22/test/with_dummyserver/test_poolmanager.py 2019-05-13 14:16:47.301691266 -0400 +@@ -108,6 +108,35 @@ class TestPoolManager(HTTPDummyServerTes + except MaxRetryError: + pass + ++ def test_redirect_cross_host_strip_auth_headers(self): ++ http = PoolManager() ++ self.addCleanup(http.clear) ++ ++ r = http.request('GET', '%s/redirect' % self.base_url, ++ fields={'target': '%s/headers' % self.base_url_alt}, ++ headers={'Authentication': 'foo'}) ++ ++ self.assertEqual(r.status, 200) ++ ++ data = json.loads(r.data.decode('utf-8')) ++ ++ self.assertNotIn('Authentication', data) ++ ++ def test_redirect_cross_host_forward_auth_headers(self): ++ http = PoolManager() ++ self.addCleanup(http.clear) ++ ++ r = http.request('GET', '%s/redirect' % self.base_url, ++ fields={'target': '%s/headers' % self.base_url_alt}, ++ headers={'Authentication': 'foo'}, ++ retries=Retry(forward_auth_headers_across_hosts=True)) ++ ++ self.assertEqual(r.status, 200) ++ ++ data = json.loads(r.data.decode('utf-8')) ++ ++ self.assertEqual(data['Authentication'], 'foo') ++ + def test_raise_on_redirect(self): + http = PoolManager() + self.addCleanup(http.clear) +Index: python-urllib3-1.22/urllib3/poolmanager.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/poolmanager.py 2019-05-13 14:16:47.301691266 -0400 ++++ python-urllib3-1.22/urllib3/poolmanager.py 2019-05-13 14:16:47.301691266 -0400 +@@ -312,8 +312,11 @@ class PoolManager(RequestMethods): + + kw['assert_same_host'] = False + kw['redirect'] = False ++ + if 'headers' not in kw: +- kw['headers'] = self.headers ++ kw['headers'] = headers = self.headers ++ else: ++ headers = kw['headers'] + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) +@@ -335,6 +338,13 @@ class PoolManager(RequestMethods): + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + ++ # Strip the Authentication header if redirecting to a new host ++ # and we don't want to forward that header across hosts. ++ if (not retries.forward_auth_headers_across_hosts ++ and 'Authentication' in headers ++ and not conn.is_same_host(redirect_location)): ++ headers.pop('Authentication') ++ + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: +@@ -344,6 +354,7 @@ class PoolManager(RequestMethods): + + kw['retries'] = retries + kw['redirect'] = redirect ++ kw['headers'] = headers + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-5.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-5.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-5.patch 2019-05-13 18:16:54.000000000 +0000 @@ -0,0 +1,52 @@ +From 5e9c6b9175d66170ef65fc703f2e46788a59ca0c Mon Sep 17 00:00:00 2001 +From: SethMichaelLarson +Date: Sun, 25 Mar 2018 20:52:13 -0500 +Subject: [PATCH] Fix AppEngine connection pool tests + +--- + test/appengine/test_gae_manager.py | 4 ++++ + test/with_dummyserver/test_connectionpool.py | 9 ++++++--- + 2 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/test/appengine/test_gae_manager.py b/test/appengine/test_gae_manager.py +index 95838ef89..2eb1861e0 100644 +--- a/test/appengine/test_gae_manager.py ++++ b/test/appengine/test_gae_manager.py +@@ -176,6 +176,10 @@ def test_retry_return_in_response(self): + test_retry_redirect_history = None + test_multi_redirect_history = None + ++ # GAE doesn't have the assert_same_host parameter in urlopen() ++ test_redirect_cross_host_forward_auth_headers = None ++ test_redirect_cross_host_no_forward_auth_headers = None ++ + + @pytest.mark.usefixtures('testbed') + class TestGAERetryAfter(test_connectionpool.TestRetryAfter): +diff --git a/test/with_dummyserver/test_connectionpool.py b/test/with_dummyserver/test_connectionpool.py +index 2e84a5370..bc6a7878e 100644 +--- a/test/with_dummyserver/test_connectionpool.py ++++ b/test/with_dummyserver/test_connectionpool.py +@@ -12,8 +12,7 @@ + from .. import ( + TARPIT_HOST, + VALID_SOURCE_ADDRESSES, +- INVALID_SOURCE_ADDRESSES, +- requires_network ++ INVALID_SOURCE_ADDRESSES + ) + from ..port_helpers import find_unused_port + from urllib3 import ( +@@ -884,7 +883,11 @@ def test_redirect_cross_host_forward_auth_headers(self): + headers = {'Authentication': 'foo'} + retry = Retry(redirect=2, forward_auth_headers_across_hosts=True) + +- resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False, retries=retry) ++ resp = self.pool.urlopen( ++ 'GET', url, headers=headers, ++ assert_same_host=False, ++ retries=retry ++ ) + + self.assertEqual(resp.status, 200) + diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-6.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-6.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-6.patch 2019-05-13 18:17:06.000000000 +0000 @@ -0,0 +1,295 @@ +From 9c9dd6f3014e89bb9c532b641abcf1b24c3896ab Mon Sep 17 00:00:00 2001 +From: lars4839 +Date: Mon, 26 Mar 2018 20:33:19 -0500 +Subject: [PATCH] Switch to Retry.remove_headers_on_redirect + +- Default to Authorization header. +- Allow different settings on the Retry object. +- Remove logic from ConnectionPool. +--- + CHANGES.rst | 6 ++-- + test/appengine/test_gae_manager.py | 4 --- + test/test_retry.py | 10 ++++++ + test/with_dummyserver/test_connectionpool.py | 36 +------------------- + test/with_dummyserver/test_poolmanager.py | 31 +++++++++++++---- + urllib3/connectionpool.py | 7 ---- + urllib3/poolmanager.py | 10 +++--- + urllib3/util/retry.py | 19 ++++++----- + 8 files changed, 54 insertions(+), 69 deletions(-) + +#diff --git a/CHANGES.rst b/CHANGES.rst +#index 35334c8c4..3e13c59ac 100644 +#--- a/CHANGES.rst +#+++ b/CHANGES.rst +#@@ -18,9 +18,9 @@ dev (master) +# +# * Lazily load `uuid` to boost performance on imports (Pull #1270) +# +#-* Stop forwarding the ``Authentication`` HTTP header on a cross-host +#- redirect unless disabled by setting ``forward_auth_headers_across_hosts`` +#- to True on ``Retry`` objects. (Issue #1316) +#+* Allow providing a list of headers to strip from requests when redirecting +#+ to a different host. Defaults to the ``Authorization`` header. Different +#+ headers can be set via ``Retry.remove_headers_on_redirect``. (Issue #1316) +# +# * ... [Short description of non-trivial change.] (Issue #) +# +Index: python-urllib3-1.22/test/appengine/test_gae_manager.py +=================================================================== +--- python-urllib3-1.22.orig/test/appengine/test_gae_manager.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/test/appengine/test_gae_manager.py 2019-05-13 14:17:03.825757706 -0400 +@@ -176,10 +176,6 @@ class TestGAERetry(test_connectionpool.T + test_retry_redirect_history = None + test_multi_redirect_history = None + +- # GAE doesn't have the assert_same_host parameter in urlopen() +- test_redirect_cross_host_forward_auth_headers = None +- test_redirect_cross_host_no_forward_auth_headers = None +- + + @pytest.mark.usefixtures('testbed') + class TestGAERetryAfter(test_connectionpool.TestRetryAfter): +Index: python-urllib3-1.22/test/test_retry.py +=================================================================== +--- python-urllib3-1.22.orig/test/test_retry.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/test/test_retry.py 2019-05-13 14:17:03.825757706 -0400 +@@ -249,3 +249,13 @@ class TestRetry(object): + retry = Retry() + with pytest.raises(ReadTimeoutError): + retry.increment(method='POST', error=error) ++ ++ def test_retry_default_remove_headers_on_redirect(self): ++ retry = Retry() ++ ++ assert list(retry.remove_headers_on_redirect) == ['Authorization'] ++ ++ def test_retry_set_remove_headers_on_redirect(self): ++ retry = Retry(remove_headers_on_redirect=['X-API-Secret']) ++ ++ assert list(retry.remove_headers_on_redirect) == ['X-API-Secret'] +Index: python-urllib3-1.22/test/with_dummyserver/test_connectionpool.py +=================================================================== +--- python-urllib3-1.22.orig/test/with_dummyserver/test_connectionpool.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/test/with_dummyserver/test_connectionpool.py 2019-05-13 14:17:03.825757706 -0400 +@@ -5,14 +5,11 @@ import sys + import unittest + import time + import warnings +-import json + + import mock + + from .. import ( +- TARPIT_HOST, +- VALID_SOURCE_ADDRESSES, +- INVALID_SOURCE_ADDRESSES ++ TARPIT_HOST, VALID_SOURCE_ADDRESSES, INVALID_SOURCE_ADDRESSES, + ) + from ..port_helpers import find_unused_port + from urllib3 import ( +@@ -746,8 +743,6 @@ class TestRetry(HTTPDummyServerTestCase) + self.pool = HTTPConnectionPool(self.host, self.port) + self.addCleanup(self.pool.close) + +- self.base_url_alt = 'http://%s:%d' % (self.host_alt, self.port) +- + def test_max_retry(self): + try: + r = self.pool.request('GET', '/redirect', +@@ -866,35 +861,6 @@ class TestRetry(HTTPDummyServerTestCase) + actual = [(history.status, history.redirect_location) for history in r.retries.history] + self.assertEqual(actual, expected) + +- def test_redirect_cross_host_no_forward_auth_headers(self): +- url = '/redirect?target=%s/headers' % self.base_url_alt +- headers = {'Authentication': 'foo'} +- +- resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False) +- +- self.assertEqual(resp.status, 200) +- +- data = json.loads(resp.data.decode('utf-8')) +- +- self.assertNotIn('Authentication', data) +- +- def test_redirect_cross_host_forward_auth_headers(self): +- url = '/redirect?target=%s/headers' % self.base_url_alt +- headers = {'Authentication': 'foo'} +- retry = Retry(redirect=2, forward_auth_headers_across_hosts=True) +- +- resp = self.pool.urlopen( +- 'GET', url, headers=headers, +- assert_same_host=False, +- retries=retry +- ) +- +- self.assertEqual(resp.status, 200) +- +- data = json.loads(resp.data.decode('utf-8')) +- +- self.assertEqual(data['Authentication'], 'foo') +- + + class TestRetryAfter(HTTPDummyServerTestCase): + def setUp(self): +Index: python-urllib3-1.22/test/with_dummyserver/test_poolmanager.py +=================================================================== +--- python-urllib3-1.22.orig/test/with_dummyserver/test_poolmanager.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/test/with_dummyserver/test_poolmanager.py 2019-05-13 14:17:03.825757706 -0400 +@@ -108,34 +108,51 @@ class TestPoolManager(HTTPDummyServerTes + except MaxRetryError: + pass + +- def test_redirect_cross_host_strip_auth_headers(self): ++ def test_redirect_cross_host_remove_headers(self): + http = PoolManager() + self.addCleanup(http.clear) + + r = http.request('GET', '%s/redirect' % self.base_url, + fields={'target': '%s/headers' % self.base_url_alt}, +- headers={'Authentication': 'foo'}) ++ headers={'Authorization': 'foo'}) + + self.assertEqual(r.status, 200) + + data = json.loads(r.data.decode('utf-8')) + +- self.assertNotIn('Authentication', data) ++ self.assertNotIn('Authorization', data) + +- def test_redirect_cross_host_forward_auth_headers(self): ++ def test_redirect_cross_host_no_remove_headers(self): + http = PoolManager() + self.addCleanup(http.clear) + + r = http.request('GET', '%s/redirect' % self.base_url, + fields={'target': '%s/headers' % self.base_url_alt}, +- headers={'Authentication': 'foo'}, +- retries=Retry(forward_auth_headers_across_hosts=True)) ++ headers={'Authorization': 'foo'}, ++ retries=Retry(remove_headers_on_redirect=[])) + + self.assertEqual(r.status, 200) + + data = json.loads(r.data.decode('utf-8')) + +- self.assertEqual(data['Authentication'], 'foo') ++ self.assertEqual(data['Authorization'], 'foo') ++ ++ def test_redirect_cross_host_set_removed_headers(self): ++ http = PoolManager() ++ self.addCleanup(http.clear) ++ ++ r = http.request('GET', '%s/redirect' % self.base_url, ++ fields={'target': '%s/headers' % self.base_url_alt}, ++ headers={'X-API-Secret': 'foo', ++ 'Authorization': 'bar'}, ++ retries=Retry(remove_headers_on_redirect=['X-API-Secret'])) ++ ++ self.assertEqual(r.status, 200) ++ ++ data = json.loads(r.data.decode('utf-8')) ++ ++ self.assertNotIn('X-API-Secret', data) ++ self.assertEqual(data['Authorization'], 'bar') + + def test_raise_on_redirect(self): + http = PoolManager() +Index: python-urllib3-1.22/urllib3/connectionpool.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/connectionpool.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/urllib3/connectionpool.py 2019-05-13 14:17:03.825757706 -0400 +@@ -695,13 +695,6 @@ class HTTPConnectionPool(ConnectionPool, + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + +- # Strip the Authentication header if redirecting to a new host +- # and we don't want to forward that header across hosts. +- if (not retries.forward_auth_headers_across_hosts +- and 'Authentication' in headers +- and not self.is_same_host(redirect_location)): +- headers.pop('Authentication') +- + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( +Index: python-urllib3-1.22/urllib3/poolmanager.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/poolmanager.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/urllib3/poolmanager.py 2019-05-13 14:17:03.825757706 -0400 +@@ -338,12 +338,12 @@ class PoolManager(RequestMethods): + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + +- # Strip the Authentication header if redirecting to a new host +- # and we don't want to forward that header across hosts. +- if (not retries.forward_auth_headers_across_hosts +- and 'Authentication' in headers ++ # Strip headers marked as unsafe to forward to the redirected location. ++ if (retries.remove_headers_on_redirect + and not conn.is_same_host(redirect_location)): +- headers.pop('Authentication') ++ for header in retries.remove_headers_on_redirect: ++ if header in headers: ++ headers.pop(header) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) +Index: python-urllib3-1.22/urllib3/util/retry.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/util/retry.py 2019-05-13 14:17:03.825757706 -0400 ++++ python-urllib3-1.22/urllib3/util/retry.py 2019-05-13 14:17:03.825757706 -0400 +@@ -139,10 +139,10 @@ class Retry(object): + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + +- :param bool forward_auth_headers_across_hosts: +- Whether to forward Authentication headers if a response is received +- that redirects to a different host than the original request. +- Defaults to False. ++ :param iterable remove_headers_on_redirect: ++ Sequence of headers to remove from the request when a response ++ indicating a redirect is returned before firing off the redirected ++ request. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ +@@ -157,7 +157,7 @@ class Retry(object): + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True, +- forward_auth_headers_across_hosts=False): ++ remove_headers_on_redirect=None): + + self.total = total + self.connect = connect +@@ -168,6 +168,10 @@ class Retry(object): + redirect = 0 + raise_on_redirect = False + ++ if remove_headers_on_redirect is None: ++ remove_headers_on_redirect = ['Authorization'] ++ remove_headers_on_redirect = set(remove_headers_on_redirect) ++ + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist +@@ -176,8 +180,7 @@ class Retry(object): + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header +- self.forward_auth_headers_across_hosts = \ +- forward_auth_headers_across_hosts ++ self.remove_headers_on_redirect = remove_headers_on_redirect + + def new(self, **kw): + params = dict( +@@ -189,7 +192,7 @@ class Retry(object): + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, +- forward_auth_headers_across_hosts=self.forward_auth_headers_across_hosts ++ remove_headers_on_redirect=self.remove_headers_on_redirect + ) + params.update(kw) + return type(self)(**params) diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-7.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-7.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-7.patch 2019-05-13 18:17:09.000000000 +0000 @@ -0,0 +1,42 @@ +From 6245ddddb7f80740c5c15e1750e5b9f68c5b2b5f Mon Sep 17 00:00:00 2001 +From: "Seth M. Larson" +Date: Tue, 27 Mar 2018 13:14:11 -0500 +Subject: [PATCH] Stop using headers, instead use kw['headers'] + +--- + urllib3/poolmanager.py | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/urllib3/poolmanager.py b/urllib3/poolmanager.py +index 53732626e..0e4525f9c 100644 +--- a/urllib3/poolmanager.py ++++ b/urllib3/poolmanager.py +@@ -314,9 +314,7 @@ def urlopen(self, method, url, redirect=True, **kw): + kw['redirect'] = False + + if 'headers' not in kw: +- kw['headers'] = headers = self.headers +- else: +- headers = kw['headers'] ++ kw['headers'] = self.headers.copy() + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) +@@ -342,8 +340,7 @@ def urlopen(self, method, url, redirect=True, **kw): + if (retries.remove_headers_on_redirect + and not conn.is_same_host(redirect_location)): + for header in retries.remove_headers_on_redirect: +- if header in headers: +- headers.pop(header) ++ kw['headers'].pop(header, None) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) +@@ -354,7 +351,6 @@ def urlopen(self, method, url, redirect=True, **kw): + + kw['retries'] = retries + kw['redirect'] = redirect +- kw['headers'] = headers + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-8.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-8.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-8.patch 2019-05-13 18:17:14.000000000 +0000 @@ -0,0 +1,33 @@ +From 3b5f27449e153ad05186beca8fbd9b134936fe50 Mon Sep 17 00:00:00 2001 +From: "Seth M. Larson" +Date: Tue, 27 Mar 2018 14:35:58 -0500 +Subject: [PATCH] Add a default list of headers to strip as a global + +--- + urllib3/util/retry.py | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/urllib3/util/retry.py b/urllib3/util/retry.py +index ae4401143..37a3a74e9 100644 +--- a/urllib3/util/retry.py ++++ b/urllib3/util/retry.py +@@ -19,6 +19,10 @@ + + log = logging.getLogger(__name__) + ++ ++DEFAULT_REDIRECT_HEADERS_BLACKLIST = ['Authorization'] ++ ++ + # Data structure for representing the metadata of requests that result in a retry. + RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) +@@ -169,7 +173,7 @@ def __init__(self, total=10, connect=None, read=None, redirect=None, status=None + raise_on_redirect = False + + if remove_headers_on_redirect is None: +- remove_headers_on_redirect = ['Authorization'] ++ remove_headers_on_redirect = DEFAULT_REDIRECT_HEADERS_BLACKLIST + remove_headers_on_redirect = set(remove_headers_on_redirect) + + self.redirect = redirect diff -Nru python-urllib3-1.22/debian/patches/CVE-2018-20060-9.patch python-urllib3-1.22/debian/patches/CVE-2018-20060-9.patch --- python-urllib3-1.22/debian/patches/CVE-2018-20060-9.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2018-20060-9.patch 2019-05-13 18:17:18.000000000 +0000 @@ -0,0 +1,22 @@ +From 1742538d57865e61125c6c12a755b5db41636fe7 Mon Sep 17 00:00:00 2001 +From: "Seth M. Larson" +Date: Tue, 27 Mar 2018 14:40:38 -0500 +Subject: [PATCH] Add a comment about short-circuiting is_same_host + +--- + urllib3/poolmanager.py | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/urllib3/poolmanager.py b/urllib3/poolmanager.py +index 0e4525f9c..506a3c9b8 100644 +--- a/urllib3/poolmanager.py ++++ b/urllib3/poolmanager.py +@@ -337,6 +337,8 @@ def urlopen(self, method, url, redirect=True, **kw): + retries = Retry.from_int(retries, redirect=redirect) + + # Strip headers marked as unsafe to forward to the redirected location. ++ # Check remove_headers_on_redirect to avoid a potential network call within ++ # conn.is_same_host() which may use socket.gethostbyname() in the future. + if (retries.remove_headers_on_redirect + and not conn.is_same_host(redirect_location)): + for header in retries.remove_headers_on_redirect: diff -Nru python-urllib3-1.22/debian/patches/CVE-2019-11236-1.patch python-urllib3-1.22/debian/patches/CVE-2019-11236-1.patch --- python-urllib3-1.22/debian/patches/CVE-2019-11236-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2019-11236-1.patch 2019-05-13 18:24:22.000000000 +0000 @@ -0,0 +1,132 @@ +Backport of: + +From 9b76785331243689a9d52cef3db05ef7462cb02d Mon Sep 17 00:00:00 2001 +From: Ryan Petrello +Date: Wed, 1 May 2019 13:11:20 -0400 +Subject: [PATCH] Apply fix from CPython for CVE-2019-9740 (#1591) + +--- + src/urllib3/connection.py | 2 +- + src/urllib3/connectionpool.py | 2 +- + src/urllib3/contrib/pyopenssl.py | 4 ++-- + src/urllib3/contrib/socks.py | 2 +- + src/urllib3/poolmanager.py | 2 +- + src/urllib3/response.py | 4 +++- + src/urllib3/util/ssl_.py | 2 -- + src/urllib3/util/url.py | 8 +++++++ + test/__init__.py | 29 +++++++++++++++++++++++ + test/test_util.py | 5 ++++ + test/with_dummyserver/test_https.py | 4 ++++ + test/with_dummyserver/test_socketlevel.py | 2 ++ + tox.ini | 2 +- + 13 files changed, 58 insertions(+), 10 deletions(-) + +Index: python-urllib3-1.22/urllib3/connection.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/connection.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/urllib3/connection.py 2019-05-13 14:19:38.490365555 -0400 +@@ -140,7 +140,7 @@ class HTTPConnection(_HTTPConnection, ob + conn = connection.create_connection( + (self.host, self.port), self.timeout, **extra_kw) + +- except SocketTimeout as e: ++ except SocketTimeout: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) +Index: python-urllib3-1.22/urllib3/connectionpool.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/connectionpool.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/urllib3/connectionpool.py 2019-05-13 14:19:38.490365555 -0400 +@@ -673,7 +673,7 @@ class HTTPConnectionPool(ConnectionPool, + # released back to the pool once the entire response is read + response.read() + except (TimeoutError, HTTPException, SocketError, ProtocolError, +- BaseSSLError, SSLError) as e: ++ BaseSSLError, SSLError): + pass + + # Handle redirect? +Index: python-urllib3-1.22/urllib3/contrib/pyopenssl.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/contrib/pyopenssl.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/urllib3/contrib/pyopenssl.py 2019-05-13 14:19:38.490365555 -0400 +@@ -261,7 +261,7 @@ class WrappedSocket(object): + return b'' + else: + raise SocketError(str(e)) +- except OpenSSL.SSL.ZeroReturnError as e: ++ except OpenSSL.SSL.ZeroReturnError: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: +@@ -283,7 +283,7 @@ class WrappedSocket(object): + return 0 + else: + raise SocketError(str(e)) +- except OpenSSL.SSL.ZeroReturnError as e: ++ except OpenSSL.SSL.ZeroReturnError: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: +Index: python-urllib3-1.22/urllib3/contrib/socks.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/contrib/socks.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/urllib3/contrib/socks.py 2019-05-13 14:19:38.490365555 -0400 +@@ -88,7 +88,7 @@ class SOCKSConnection(HTTPConnection): + **extra_kw + ) + +- except SocketTimeout as e: ++ except SocketTimeout: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) +Index: python-urllib3-1.22/urllib3/util/url.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/util/url.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/urllib3/util/url.py 2019-05-13 14:19:38.490365555 -0400 +@@ -1,5 +1,6 @@ + from __future__ import absolute_import + from collections import namedtuple ++import re + + from ..exceptions import LocationParseError + +@@ -10,6 +11,8 @@ url_attrs = ['scheme', 'auth', 'host', ' + # urllib3 infers URLs without a scheme (None) to be http. + NORMALIZABLE_SCHEMES = ('http', 'https', None) + ++_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]') ++ + + class Url(namedtuple('Url', url_attrs)): + """ +@@ -155,6 +158,11 @@ def parse_url(url): + # Empty + return Url() + ++ # Prevent CVE-2019-9740. ++ # adapted from https://github.com/python/cpython/pull/12755 ++ if _contains_disallowed_url_pchar_re.search(url): ++ raise LocationParseError("URL can't contain control characters. {!r}".format(url)) ++ + scheme = None + auth = None + host = None +Index: python-urllib3-1.22/test/test_util.py +=================================================================== +--- python-urllib3-1.22.orig/test/test_util.py 2019-05-13 14:19:38.494365571 -0400 ++++ python-urllib3-1.22/test/test_util.py 2019-05-13 14:19:38.494365571 -0400 +@@ -199,6 +199,11 @@ class TestUtil(object): + with pytest.raises(ValueError): + parse_url('[::1') + ++ def test_parse_url_contains_control_characters(self): ++ # see CVE-2019-9740 ++ with pytest.raises(LocationParseError): ++ parse_url('http://localhost:8000/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:') ++ + def test_Url_str(self): + U = Url('http', host='google.com') + assert str(U) == U.url diff -Nru python-urllib3-1.22/debian/patches/CVE-2019-11236-2.patch python-urllib3-1.22/debian/patches/CVE-2019-11236-2.patch --- python-urllib3-1.22/debian/patches/CVE-2019-11236-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2019-11236-2.patch 2019-05-13 18:27:58.000000000 +0000 @@ -0,0 +1,69 @@ +Backport of: + +From efddd7e7bad26188c3b692d1090cba768afa9162 Mon Sep 17 00:00:00 2001 +From: Ryan Petrello +Date: Thu, 2 May 2019 11:03:09 -0400 +Subject: [PATCH] Avoid CVE-2019-9740 in 1.24.x by percent-encoding invalid + target characters (#1593) + +--- + src/urllib3/util/url.py | 4 ++-- + test/test_util.py | 22 +++++++++++++++++++--- + 2 files changed, 21 insertions(+), 5 deletions(-) + +Index: python-urllib3-1.22/urllib3/util/url.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/util/url.py 2019-05-13 14:25:01.911576410 -0400 ++++ python-urllib3-1.22/urllib3/util/url.py 2019-05-13 14:25:01.907576396 -0400 +@@ -3,6 +3,7 @@ from collections import namedtuple + import re + + from ..exceptions import LocationParseError ++from ..packages.six.moves.urllib.parse import quote + + + url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] +@@ -160,8 +161,7 @@ def parse_url(url): + + # Prevent CVE-2019-9740. + # adapted from https://github.com/python/cpython/pull/12755 +- if _contains_disallowed_url_pchar_re.search(url): +- raise LocationParseError("URL can't contain control characters. {!r}".format(url)) ++ url = _contains_disallowed_url_pchar_re.sub(lambda match: quote(match.group()), url) + + scheme = None + auth = None +Index: python-urllib3-1.22/test/test_util.py +=================================================================== +--- python-urllib3-1.22.orig/test/test_util.py 2019-05-13 14:25:01.911576410 -0400 ++++ python-urllib3-1.22/test/test_util.py 2019-05-13 14:25:01.907576396 -0400 +@@ -199,10 +199,26 @@ class TestUtil(object): + with pytest.raises(ValueError): + parse_url('[::1') + +- def test_parse_url_contains_control_characters(self): ++ @pytest.mark.parametrize('url, expected_url', [ ++ ( ++ 'http://localhost/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:', ++ Url('http', host='localhost', port=None, ++ path='/%20HTTP/1.1%0D%0AHEADER:%20INJECTED%0D%0AIgnore:') ++ ), ++ ( ++ u'http://localhost/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:', ++ Url('http', host='localhost', port=None, ++ path='/%20HTTP/1.1%0D%0AHEADER:%20INJECTED%0D%0AIgnore:') ++ ), ++ ( ++ 'http://localhost/ ?q=\r\n', ++ Url('http', host='localhost', path='/%20', query='q=%0D%0A') ++ ), ++ ]) ++ def test_parse_url_contains_control_characters(self, url, expected_url): + # see CVE-2019-9740 +- with pytest.raises(LocationParseError): +- parse_url('http://localhost:8000/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:') ++ url = parse_url(url) ++ assert url == expected_url + + def test_Url_str(self): + U = Url('http', host='google.com') diff -Nru python-urllib3-1.22/debian/patches/CVE-2019-11236-3.patch python-urllib3-1.22/debian/patches/CVE-2019-11236-3.patch --- python-urllib3-1.22/debian/patches/CVE-2019-11236-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2019-11236-3.patch 2019-05-13 18:25:22.000000000 +0000 @@ -0,0 +1,17 @@ +Description: don't use embedded python-six +Author: Marc Deslauriers +Forwarded: Not needed. Specific to Debian packaging. + +Index: python-urllib3-1.24.1/urllib3/util/url.py +=================================================================== +--- python-urllib3-1.24.1.orig/urllib3/util/url.py 2019-05-13 13:44:41.509708019 -0400 ++++ python-urllib3-1.24.1/urllib3/util/url.py 2019-05-13 13:45:07.617788063 -0400 +@@ -3,7 +3,7 @@ from collections import namedtuple + import re + + from ..exceptions import LocationParseError +-from ..packages.six.moves.urllib.parse import quote ++from six.moves.urllib.parse import quote + + + url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] diff -Nru python-urllib3-1.22/debian/patches/CVE-2019-11324.patch python-urllib3-1.22/debian/patches/CVE-2019-11324.patch --- python-urllib3-1.22/debian/patches/CVE-2019-11324.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/CVE-2019-11324.patch 2019-05-13 18:27:55.000000000 +0000 @@ -0,0 +1,44 @@ +Partial backport of: + +From 1efadf43dc63317cd9eaa3e0fdb9e05ab07254b1 Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Wed, 17 Apr 2019 12:46:22 -0500 +Subject: [PATCH] Release 1.24.2 (#1564) + +* Don't load system certificates by default when any other ``ca_certs``, ``ca_certs_dir`` or ``ssl_context`` parameters are specified. +* Remove Authorization header regardless of case when redirecting to cross-site. (Issue #1510) +* Add support for IPv6 addresses in subjectAltName section of certificates. (Issue #1269) +--- + CHANGES.rst | 13 +++++++- + CONTRIBUTORS.txt | 3 ++ + dummyserver/certs/server.ipv6_san.crt | 16 ++++++++++ + dummyserver/server.py | 5 +++ + src/urllib3/__init__.py | 2 +- + src/urllib3/contrib/pyopenssl.py | 3 ++ + src/urllib3/poolmanager.py | 7 +++-- + src/urllib3/util/retry.py | 3 +- + src/urllib3/util/ssl_.py | 5 ++- + test/contrib/test_pyopenssl.py | 5 ++- + test/test_retry.py | 6 ++-- + test/test_ssl.py | 37 +++++++++++++++++++++++ + test/with_dummyserver/test_https.py | 20 +++++++++++- + test/with_dummyserver/test_poolmanager.py | 26 ++++++++++++++++ + 14 files changed, 140 insertions(+), 11 deletions(-) + create mode 100644 dummyserver/certs/server.ipv6_san.crt + +Index: python-urllib3-1.22/urllib3/util/ssl_.py +=================================================================== +--- python-urllib3-1.22.orig/urllib3/util/ssl_.py 2019-05-13 14:27:52.704194258 -0400 ++++ python-urllib3-1.22/urllib3/util/ssl_.py 2019-05-13 14:27:52.700194243 -0400 +@@ -319,7 +319,10 @@ def ssl_wrap_socket(sock, keyfile=None, + if e.errno == errno.ENOENT: + raise SSLError(e) + raise +- elif getattr(context, 'load_default_certs', None) is not None: ++ ++ # Don't load system certs unless there were no CA certs or ++ # SSLContext object specified manually. ++ elif ssl_context is None and hasattr(context, 'load_default_certs'): + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + diff -Nru python-urllib3-1.22/debian/patches/fix_cert_error.patch python-urllib3-1.22/debian/patches/fix_cert_error.patch --- python-urllib3-1.22/debian/patches/fix_cert_error.patch 1970-01-01 00:00:00.000000000 +0000 +++ python-urllib3-1.22/debian/patches/fix_cert_error.patch 2019-05-13 18:27:58.000000000 +0000 @@ -0,0 +1,22 @@ +From edd7a0063d25f1a7f34306f9a9488247593888a9 Mon Sep 17 00:00:00 2001 +From: Chris Wilcox +Date: Fri, 20 Apr 2018 15:50:40 -0700 +Subject: [PATCH] Address #1365. CertificateError str repr is tuple, not str. + +--- + test/test_connection.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/test_connection.py b/test/test_connection.py +index be50f6c49..dfc757d70 100644 +--- a/test/test_connection.py ++++ b/test/test_connection.py +@@ -38,7 +38,7 @@ def test_match_hostname_mismatch(self): + with mock.patch('urllib3.connection.log.error') as mock_log: + _match_hostname(cert, asserted_hostname) + except CertificateError as e: +- assert str(e) == "hostname 'bar' doesn't match 'foo'" ++ assert "hostname 'bar' doesn't match 'foo'" in str(e) + mock_log.assert_called_once_with( + 'Certificate did not match expected hostname: %s. ' + 'Certificate: %s', diff -Nru python-urllib3-1.22/debian/patches/series python-urllib3-1.22/debian/patches/series --- python-urllib3-1.22/debian/patches/series 2018-01-04 13:58:38.000000000 +0000 +++ python-urllib3-1.22/debian/patches/series 2019-05-13 18:27:58.000000000 +0000 @@ -2,3 +2,18 @@ 02_require-cert-verification.patch 04_relax_nosetests_options.patch 05_avoid-embedded-ssl-match-hostname.patch +CVE-2018-20060-1.patch +CVE-2018-20060-2.patch +CVE-2018-20060-3.patch +CVE-2018-20060-5.patch +CVE-2018-20060-6.patch +CVE-2018-20060-7.patch +CVE-2018-20060-8.patch +CVE-2018-20060-9.patch +CVE-2018-20060-10.patch +CVE-2018-20060-12.patch +CVE-2019-11236-1.patch +CVE-2019-11236-2.patch +CVE-2019-11236-3.patch +CVE-2019-11324.patch +fix_cert_error.patch