| From aab3e8c432b90508ac14755128f5a687be2fdf43 Mon Sep 17 00:00:00 2001 |
| From: Mingli Yu <Mingli.Yu@windriver.com> |
| Date: Thu, 22 Sep 2016 16:39:49 +0800 |
| Subject: [PATCH] python3: fix CVE-2016-1000110 |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| 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. [#27568] |
| |
| Backport patch from https://hg.python.org/cpython/rev/a0ac52ed8f79 |
| |
| Upstream-Status: Backport |
| CVE: CVE-2016-1000110 |
| Signed-off-by: Mingli Yu <Mingli.Yu@windriver.com> |
| --- |
| Doc/howto/urllib2.rst | 5 +++++ |
| Doc/library/urllib.request.rst | 17 ++++++++++++++++- |
| Lib/test/test_urllib.py | 14 +++++++++++++- |
| Lib/urllib/request.py | 6 ++++++ |
| Misc/NEWS | 4 ++++ |
| 5 files changed, 44 insertions(+), 2 deletions(-) |
| |
| diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst |
| index 24a4156..d2c7991 100644 |
| --- a/Doc/howto/urllib2.rst |
| +++ b/Doc/howto/urllib2.rst |
| @@ -538,6 +538,11 @@ setting up a `Basic Authentication`_ handler: :: |
| 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 |
| index 1338906..1291aeb 100644 |
| --- a/Doc/library/urllib.request.rst |
| +++ b/Doc/library/urllib.request.rst |
| @@ -173,6 +173,16 @@ The :mod:`urllib.request` module defines the following functions: |
| If both lowercase and uppercase environment variables exist (and disagree), |
| lowercase is preferred. |
| |
| + .. 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, either use |
| + ``ProxyHandler`` explicitly, or make sure the variable name is in |
| + lowercase (or at least the ``_proxy`` suffix). |
| + |
| |
| The following classes are provided: |
| |
| @@ -280,6 +290,11 @@ The following classes are provided: |
| list of hostname suffixes, optionally with ``:port`` appended, for example |
| ``cern.ch,ncsa.uiuc.edu,some.host:8080``. |
| |
| + .. note:: |
| + |
| + ``HTTP_PROXY`` will be ignored if a variable ``REQUEST_METHOD`` is set; |
| + see the documentation on :func:`~urllib.request.getproxies`. |
| + |
| |
| .. class:: HTTPPasswordMgr() |
| |
| @@ -1138,7 +1153,7 @@ the returned bytes object to string once it determines or guesses |
| the appropriate encoding. |
| |
| The following W3C document, https://www.w3.org/International/O-charset\ , lists |
| -the various ways in which a (X)HTML or a XML document could have specified its |
| +the various ways in which an (X)HTML or an XML document could have specified its |
| encoding information. |
| |
| As the python.org website uses *utf-8* encoding as specified in its meta tag, we |
| diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py |
| index 5d05f8d..247598a 100644 |
| --- a/Lib/test/test_urllib.py |
| +++ b/Lib/test/test_urllib.py |
| @@ -1,4 +1,4 @@ |
| -"""Regresssion tests for what was in Python 2's "urllib" module""" |
| +"""Regression tests for what was in Python 2's "urllib" module""" |
| |
| import urllib.parse |
| import urllib.request |
| @@ -232,6 +232,18 @@ class ProxyTests(unittest.TestCase): |
| self.assertTrue(urllib.request.proxy_bypass_environment('anotherdomain.com:8888')) |
| self.assertTrue(urllib.request.proxy_bypass_environment('newdomain.com:1234')) |
| |
| + 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') |
| + |
| def test_proxy_bypass_environment_host_match(self): |
| bypass = urllib.request.proxy_bypass_environment |
| self.env.set('NO_PROXY', |
| diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py |
| index 1731fe3..3be327d 100644 |
| --- a/Lib/urllib/request.py |
| +++ b/Lib/urllib/request.py |
| @@ -2412,6 +2412,12 @@ 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 "proxy" is lowercase, it will still be used thanks to the next block |
| + if 'REQUEST_METHOD' in os.environ: |
| + proxies.pop('http', None) |
| for name, value in os.environ.items(): |
| if name[-6:] == '_proxy': |
| name = name.lower() |
| diff --git a/Misc/NEWS b/Misc/NEWS |
| index 4ad2551..2fcc95b 100644 |
| --- a/Misc/NEWS |
| +++ b/Misc/NEWS |
| @@ -329,6 +329,10 @@ Library |
| - Issue #26644: Raise ValueError rather than SystemError when a negative |
| length is passed to SSLSocket.recv() or read(). |
| |
| +- Issue #27568: 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 #23804: Fix SSL recv(0) and read(0) methods to return zero bytes |
| instead of up to 1024. |
| |
| -- |
| 2.8.1 |
| |