diff --git a/SOURCES/00354-cve-2020-26116-http-request-method-crlf-injection-in-httplib.patch b/SOURCES/00354-cve-2020-26116-http-request-method-crlf-injection-in-httplib.patch new file mode 100644 index 0000000..aa0b385 --- /dev/null +++ b/SOURCES/00354-cve-2020-26116-http-request-method-crlf-injection-in-httplib.patch @@ -0,0 +1,73 @@ +diff --git a/Lib/http/client.py b/Lib/http/client.py +index f0d2642..0a044e9 100644 +--- a/Lib/http/client.py ++++ b/Lib/http/client.py +@@ -151,6 +151,10 @@ _contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]') + # _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") + # We are more lenient for assumed real world compatibility purposes. + ++# These characters are not allowed within HTTP method names ++# to prevent http header injection. ++_contains_disallowed_method_pchar_re = re.compile('[\x00-\x1f]') ++ + # We always set the Content-Length header for these methods because some + # servers will otherwise respond with a 411 + _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} +@@ -1117,6 +1121,8 @@ class HTTPConnection: + else: + raise CannotSendRequest(self.__state) + ++ self._validate_method(method) ++ + # Save the method we use, we need it later in the response phase + self._method = method + if not url: +@@ -1207,6 +1213,15 @@ class HTTPConnection: + # For HTTP/1.0, the server will assume "not chunked" + pass + ++ def _validate_method(self, method): ++ """Validate a method name for putrequest.""" ++ # prevent http header injection ++ match = _contains_disallowed_method_pchar_re.search(method) ++ if match: ++ raise ValueError( ++ f"method can't contain control characters. {method!r} " ++ f"(found at least {match.group()!r})") ++ + def putheader(self, header, *values): + """Send a request header line to the server. + +diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py +index 5795b7a..af0350f 100644 +--- a/Lib/test/test_httplib.py ++++ b/Lib/test/test_httplib.py +@@ -359,6 +359,28 @@ class HeaderTests(TestCase): + self.assertEqual(lines[2], "header: Second: val") + + ++class HttpMethodTests(TestCase): ++ def test_invalid_method_names(self): ++ methods = ( ++ 'GET\r', ++ 'POST\n', ++ 'PUT\n\r', ++ 'POST\nValue', ++ 'POST\nHOST:abc', ++ 'GET\nrHost:abc\n', ++ 'POST\rRemainder:\r', ++ 'GET\rHOST:\n', ++ '\nPUT' ++ ) ++ ++ for method in methods: ++ with self.assertRaisesRegex( ++ ValueError, "method can't contain control characters"): ++ conn = client.HTTPConnection('example.com') ++ conn.sock = FakeSocket(None) ++ conn.request(method=method, url="/") ++ ++ + class TransferEncodingTest(TestCase): + expected_body = b"It's just a flesh wound" + diff --git a/SPECS/python3.spec b/SPECS/python3.spec index 5e24c4e..5ce23e0 100644 --- a/SPECS/python3.spec +++ b/SPECS/python3.spec @@ -14,7 +14,7 @@ URL: https://www.python.org/ # WARNING When rebasing to a new Python version, # remember to update the python3-docs package as well Version: %{pybasever}.8 -Release: 31%{?dist} +Release: 32%{?dist} License: Python @@ -519,6 +519,12 @@ Patch351: 00351-avoid-infinite-loop-in-the-tarfile-module.patch # Fixed upstream: https://bugs.python.org/issue41004 Patch352: 00352-resolve-hash-collisions-for-ipv4interface-and-ipv6interface.patch +# 00354 # +# Reject control chars in HTTP method in http.client to prevent +# HTTP header injection +# Fixed ustream: https://bugs.python.org/issue39603 +Patch354: 00354-cve-2020-26116-http-request-method-crlf-injection-in-httplib.patch + # (New patches go here ^^^) # # When adding new patches to "python" and "python3" in Fedora, EL, etc., @@ -836,6 +842,7 @@ rm Lib/ensurepip/_bundled/*.whl %patch344 -p1 %patch345 -p1 %patch346 -p1 +%patch354 -p1 # Patch 351 adds binary file for testing. We need to apply it using Git. git apply %{PATCH351} @@ -1757,6 +1764,10 @@ fi # ====================================================== %changelog +* Mon Nov 09 2020 Charalampos Stratakis - 3.6.8-32 +- Security fix for CVE-2020-26116: Reject control chars in HTTP method in http.client +Resolves: rhbz#1883257 + * Mon Aug 17 2020 Tomas Orsava - 3.6.8-31 - Avoid infinite loop when reading specially crafted TAR files (CVE-2019-20907) Resolves: rhbz#1856481