Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions SPECS/python3/CVE-2021-28861.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
From 2f09fe26b94ede913b151cb1bb3bcef543e113a2 Mon Sep 17 00:00:00 2001
From: "Gregory P. Smith [Google]" <[email protected]>
Date: Wed, 15 Jun 2022 20:10:15 +0000
Subject: [PATCH 1/7] gh-87389: Fix an open redirection vulnerability in
http.server.

Fix an open redirection vulnerability in the `http.server` module when
an URI path starts with `//`. Vulnerability discovered, and initial fix
proposed, by Hamza Avvan.

Test authored and secondary mitigation by Gregory P. Smith [Google].

diff -ruN a/Lib/http/server.py b/Lib/http/server.py
--- a/Lib/http/server.py 2022-03-16 06:27:21.000000000 -0700
+++ b/Lib/http/server.py 2022-09-01 12:01:09.033232542 -0700
@@ -330,6 +330,13 @@
"Bad HTTP/0.9 request type (%r)" % command)
return False
self.command, self.path = command, path
+
+ # gh-87389: The purpose of replacing '//' with '/' is to protect
+ # against open redirect attacks possibly triggered if the path starts
+ # with '//' because http clients treat //path as an absolute URI
+ # without scheme (similar to http://path) rather than a path.
+ if self.path.startswith('//'):
+ self.path = '/' + self.path.lstrip('/') # Reduce to a single /

# Examine the headers and look for a Connection directive.
try:
diff -ruN a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
--- a/Lib/test/test_httpservers.py 2022-03-16 06:27:21.000000000 -0700
+++ b/Lib/test/test_httpservers.py 2022-09-01 12:04:18.385086834 -0700
@@ -329,7 +329,7 @@
pass

def setUp(self):
- BaseTestCase.setUp(self)
+ super().setUp()
self.cwd = os.getcwd()
basetempdir = tempfile.gettempdir()
os.chdir(basetempdir)
@@ -357,7 +357,7 @@
except:
pass
finally:
- BaseTestCase.tearDown(self)
+ super().tearDown()

def check_status_and_reason(self, response, status, data=None):
def close_conn():
@@ -413,6 +413,53 @@
self.check_status_and_reason(response, HTTPStatus.OK,
data=support.TESTFN_UNDECODABLE)

+ def test_get_dir_redirect_location_domain_injection_bug(self):
+ """Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location.
+ //netloc/ in a Location header is a redirect to a new host.
+ https://github.com/python/cpython/issues/87389
+ This checks that a path resolving to a directory on our server cannot
+ resolve into a redirect to another server.
+ """
+ os.mkdir(os.path.join(self.tempdir, 'existing_directory'))
+ url = f'/python.org/..%2f..%2f..%2f..%2f..%2f../%0a%0d/../{self.tempdir_name}/existing_directory'
+ expected_location = f'{url}/' # /python.org.../ single slash single prefix, trailing slash
+ # Canonicalizes to /tmp/tempdir_name/existing_directory which does
+ # exist and is a dir, triggering the 301 redirect logic.
+ response = self.request(url)
+ self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+ location = response.getheader('Location')
+ self.assertEqual(location, expected_location, msg='non-attack failed!')
+
+ # //python.org... multi-slash prefix, no trailing slash
+ attack_url = f'/{url}'
+ response = self.request(attack_url)
+ self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+ location = response.getheader('Location')
+ self.assertFalse(location.startswith('//'), msg=location)
+ self.assertEqual(location, expected_location,
+ msg='Expected Location header to start with a single / and '
+ 'end with a / as this is a directory redirect.')
+
+ # ///python.org... triple-slash prefix, no trailing slash
+ attack3_url = f'//{url}'
+ response = self.request(attack3_url)
+ self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+ self.assertEqual(response.getheader('Location'), expected_location)
+
+ # If the second word in the http request (Request-URI for the http
+ # method) is a full URI, we don't worry about it, as that'll be parsed
+ # and reassembled as a full URI within BaseHTTPRequestHandler.send_head
+ # so no errant scheme-less //netloc//evil.co/ domain mixup can happen.
+ attack_scheme_netloc_2slash_url = f'https://pypi.org/{url}'
+ expected_scheme_netloc_location = f'{attack_scheme_netloc_2slash_url}/'
+ response = self.request(attack_scheme_netloc_2slash_url)
+ self.check_status_and_reason(response, HTTPStatus.MOVED_PERMANENTLY)
+ location = response.getheader('Location')
+ # We're just ensuring that the scheme and domain make it through, if
+ # there are or aren't multiple slashes at the start of the path that
+ # follows that isn't important in this Location: header.
+ self.assertTrue(location.startswith('https://pypi.org/'), msg=location)
+
def test_get(self):
#constructs the path relative to the root directory of the HTTPServer
response = self.request(self.base_url + '/test')
diff -ruN a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS 2022-03-16 07:04:10.000000000 -0700
+++ b/Misc/NEWS 2022-09-01 14:01:37.138915508 -0700
@@ -52,6 +52,9 @@

Security
--------
+- bpo-43223: mod:`http.server`: Fix an open redirection vulnerability in
+ the HTTP server when an URL contains ``//``.
+ Vulnerability discovered and fixed by Hamza Avvan.

- bpo-44394: Update the vendored copy of libexpat to 2.4.1 (from 2.2.8) to
get the fix for the CVE-2013-0340 "Billion Laughs" vulnerability. This
6 changes: 5 additions & 1 deletion SPECS/python3/python3.spec
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Summary: A high-level scripting language
Name: python3
Version: 3.7.13
Release: 2%{?dist}
Release: 3%{?dist}
License: PSF
Vendor: Microsoft Corporation
Distribution: Mariner
Expand All @@ -14,6 +14,7 @@ Patch0: cgi3.patch
Patch1: python3-support-mariner-platform.patch
Patch2: Replace-unsupported-TLS-methods.patch
Patch3: fix_broken_mariner_ssl_tests.patch
Patch4: CVE-2021-28861.patch
BuildRequires: bzip2-devel
BuildRequires: expat-devel >= 2.1.0
BuildRequires: libffi-devel >= 3.0.13
Expand Down Expand Up @@ -278,6 +279,9 @@ make %{?_smp_mflags} test
%{_libdir}/python3.7/test/*

%changelog
* Thu Sep 01 2022 Minghe Ren <[email protected]> - 3.7.13-3
- Add patch to fix CVE-2021-28861

* Wed Jul 06 2022 Suresh Babu Chalamalasetty <[email protected]> - 3.7.13-2
- Fix for bad interpreter error when running pip3, pip3.7

Expand Down