|
|
bd5b0e |
From c734f873270cf9ca414832423f7aad98443c379f Mon Sep 17 00:00:00 2001
|
|
|
bd5b0e |
From: Lumir Balhar <lbalhar@redhat.com>
|
|
|
bd5b0e |
Date: Thu, 9 Jan 2020 11:26:24 +0100
|
|
|
bd5b0e |
Subject: [PATCH] CVE-2018-20060
|
|
|
bd5b0e |
|
|
|
bd5b0e |
---
|
|
|
bd5b0e |
poolmanager.py | 11 ++++++++++-
|
|
|
bd5b0e |
util/retry.py | 12 +++++++++++-
|
|
|
bd5b0e |
2 files changed, 21 insertions(+), 2 deletions(-)
|
|
|
bd5b0e |
|
|
|
bd5b0e |
diff --git a/poolmanager.py b/poolmanager.py
|
|
|
bd5b0e |
index 4ae9174..bfa5115 100644
|
|
|
bd5b0e |
--- a/poolmanager.py
|
|
|
bd5b0e |
+++ b/poolmanager.py
|
|
|
bd5b0e |
@@ -312,8 +312,9 @@ class PoolManager(RequestMethods):
|
|
|
bd5b0e |
|
|
|
bd5b0e |
kw['assert_same_host'] = False
|
|
|
bd5b0e |
kw['redirect'] = False
|
|
|
bd5b0e |
+
|
|
|
bd5b0e |
if 'headers' not in kw:
|
|
|
bd5b0e |
- kw['headers'] = self.headers
|
|
|
bd5b0e |
+ kw['headers'] = self.headers.copy()
|
|
|
bd5b0e |
|
|
|
bd5b0e |
if self.proxy is not None and u.scheme == "http":
|
|
|
bd5b0e |
response = conn.urlopen(method, url, **kw)
|
|
|
bd5b0e |
@@ -335,6 +336,14 @@ class PoolManager(RequestMethods):
|
|
|
bd5b0e |
if not isinstance(retries, Retry):
|
|
|
bd5b0e |
retries = Retry.from_int(retries, redirect=redirect)
|
|
|
bd5b0e |
|
|
|
bd5b0e |
+ # Strip headers marked as unsafe to forward to the redirected location.
|
|
|
bd5b0e |
+ # Check remove_headers_on_redirect to avoid a potential network call within
|
|
|
bd5b0e |
+ # conn.is_same_host() which may use socket.gethostbyname() in the future.
|
|
|
bd5b0e |
+ if (retries.remove_headers_on_redirect
|
|
|
bd5b0e |
+ and not conn.is_same_host(redirect_location)):
|
|
|
bd5b0e |
+ for header in retries.remove_headers_on_redirect:
|
|
|
bd5b0e |
+ kw['headers'].pop(header, None)
|
|
|
bd5b0e |
+
|
|
|
bd5b0e |
try:
|
|
|
bd5b0e |
retries = retries.increment(method, url, response=response, _pool=conn)
|
|
|
bd5b0e |
except MaxRetryError:
|
|
|
bd5b0e |
diff --git a/util/retry.py b/util/retry.py
|
|
|
bd5b0e |
index c603cb4..0b83963 100644
|
|
|
bd5b0e |
--- a/util/retry.py
|
|
|
bd5b0e |
+++ b/util/retry.py
|
|
|
bd5b0e |
@@ -126,6 +126,11 @@ class Retry(object):
|
|
|
bd5b0e |
exhausted, to raise a MaxRetryError, or to return a response with a
|
|
|
bd5b0e |
response code in the 3xx range.
|
|
|
bd5b0e |
|
|
|
bd5b0e |
+ :param iterable remove_headers_on_redirect:
|
|
|
bd5b0e |
+ Sequence of headers to remove from the request when a response
|
|
|
bd5b0e |
+ indicating a redirect is returned before firing off the redirected
|
|
|
bd5b0e |
+ request
|
|
|
bd5b0e |
+
|
|
|
bd5b0e |
:param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
|
|
|
bd5b0e |
whether we should raise an exception, or return a response,
|
|
|
bd5b0e |
if status falls in ``status_forcelist`` range and retries have
|
|
|
bd5b0e |
@@ -144,6 +149,8 @@ class Retry(object):
|
|
|
bd5b0e |
DEFAULT_METHOD_WHITELIST = frozenset([
|
|
|
bd5b0e |
'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE'])
|
|
|
bd5b0e |
|
|
|
bd5b0e |
+ DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization'])
|
|
|
bd5b0e |
+
|
|
|
bd5b0e |
RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
|
|
|
bd5b0e |
|
|
|
bd5b0e |
#: Maximum backoff time.
|
|
|
bd5b0e |
@@ -152,7 +159,8 @@ class Retry(object):
|
|
|
bd5b0e |
def __init__(self, total=10, connect=None, read=None, redirect=None, status=None,
|
|
|
bd5b0e |
method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None,
|
|
|
bd5b0e |
backoff_factor=0, raise_on_redirect=True, raise_on_status=True,
|
|
|
bd5b0e |
- history=None, respect_retry_after_header=True):
|
|
|
bd5b0e |
+ history=None, respect_retry_after_header=True,
|
|
|
bd5b0e |
+ remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST):
|
|
|
bd5b0e |
|
|
|
bd5b0e |
self.total = total
|
|
|
bd5b0e |
self.connect = connect
|
|
|
bd5b0e |
@@ -171,6 +179,7 @@ class Retry(object):
|
|
|
bd5b0e |
self.raise_on_status = raise_on_status
|
|
|
bd5b0e |
self.history = history or tuple()
|
|
|
bd5b0e |
self.respect_retry_after_header = respect_retry_after_header
|
|
|
bd5b0e |
+ self.remove_headers_on_redirect = remove_headers_on_redirect
|
|
|
bd5b0e |
|
|
|
bd5b0e |
def new(self, **kw):
|
|
|
bd5b0e |
params = dict(
|
|
|
bd5b0e |
@@ -182,6 +191,7 @@ class Retry(object):
|
|
|
bd5b0e |
raise_on_redirect=self.raise_on_redirect,
|
|
|
bd5b0e |
raise_on_status=self.raise_on_status,
|
|
|
bd5b0e |
history=self.history,
|
|
|
bd5b0e |
+ remove_headers_on_redirect=self.remove_headers_on_redirect,
|
|
|
bd5b0e |
)
|
|
|
bd5b0e |
params.update(kw)
|
|
|
bd5b0e |
return type(self)(**params)
|
|
|
bd5b0e |
--
|
|
|
bd5b0e |
2.24.1
|
|
|
bd5b0e |
|