https://github.com/python/cpython/commit/49fe7574d9e267fcd82269228995068744e9f0f8
commit: 49fe7574d9e267fcd82269228995068744e9f0f8
branch: 3.14
author: Hugo van Kemenade <[email protected]>
committer: hugovk <[email protected]>
date: 2025-12-02T12:06:25Z
summary:
[3.14] Revert "gh-119452: Fix a potential virtual memory allocation denial of
service in http.server (GH-119455)" (#142184)
Fix a potential virtual memory allocation denial of service in http.server
(GH-119455)"
files:
D Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst
M Lib/http/server.py
M Lib/test/test_httpservers.py
diff --git a/Lib/http/server.py b/Lib/http/server.py
index 226ca3b16ccbeb..8bb49275e78cbd 100644
--- a/Lib/http/server.py
+++ b/Lib/http/server.py
@@ -134,10 +134,6 @@
DEFAULT_ERROR_CONTENT_TYPE = "text/html;charset=utf-8"
-# Data larger than this will be read in chunks, to prevent extreme
-# overallocation.
-_MIN_READ_BUF_SIZE = 1 << 20
-
class HTTPServer(socketserver.TCPServer):
allow_reuse_address = True # Seems to make sense in testing environment
@@ -1288,16 +1284,7 @@ def run_cgi(self):
env = env
)
if self.command.lower() == "post" and nbytes > 0:
- cursize = 0
- data = self.rfile.read(min(nbytes, _MIN_READ_BUF_SIZE))
- while (len(data) < nbytes and len(data) != cursize and
- select.select([self.rfile._sock], [], [], 0)[0]):
- cursize = len(data)
- # This is a geometric increase in read size (never more
- # than doubling our the current length of data per loop
- # iteration).
- delta = min(cursize, nbytes - cursize)
- data += self.rfile.read(delta)
+ data = self.rfile.read(nbytes)
else:
data = None
# throw away additional data [see bug #427345]
diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py
index 0f003064f3109c..9539457d4d829d 100644
--- a/Lib/test/test_httpservers.py
+++ b/Lib/test/test_httpservers.py
@@ -913,20 +913,6 @@ def test_path_without_leading_slash(self):
print("</pre>")
"""
-cgi_file7 = """\
-#!%s
-import os
-import sys
-
-print("Content-type: text/plain")
-print()
-
-content_length = int(os.environ["CONTENT_LENGTH"])
-body = sys.stdin.buffer.read(content_length)
-
-print(f"{content_length} {len(body)}")
-"""
-
@unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
"This test can't be run reliably as root (issue #13308).")
@@ -966,8 +952,6 @@ def setUp(self):
self.file3_path = None
self.file4_path = None
self.file5_path = None
- self.file6_path = None
- self.file7_path = None
# The shebang line should be pure ASCII: use symlink if possible.
# See issue #7668.
@@ -1022,11 +1006,6 @@ def setUp(self):
file6.write(cgi_file6 % self.pythonexe)
os.chmod(self.file6_path, 0o777)
- self.file7_path = os.path.join(self.cgi_dir, 'file7.py')
- with open(self.file7_path, 'w', encoding='utf-8') as file7:
- file7.write(cgi_file7 % self.pythonexe)
- os.chmod(self.file7_path, 0o777)
-
os.chdir(self.parent_dir)
def tearDown(self):
@@ -1049,8 +1028,6 @@ def tearDown(self):
os.remove(self.file5_path)
if self.file6_path:
os.remove(self.file6_path)
- if self.file7_path:
- os.remove(self.file7_path)
os.rmdir(self.cgi_child_dir)
os.rmdir(self.cgi_dir)
os.rmdir(self.cgi_dir_in_sub_dir)
@@ -1123,21 +1100,6 @@ def test_post(self):
self.assertEqual(res.read(), b'1, python, 123456' + self.linesep)
- def test_large_content_length(self):
- for w in range(15, 25):
- size = 1 << w
- body = b'X' * size
- headers = {'Content-Length' : str(size)}
- res = self.request('/cgi-bin/file7.py', 'POST', body, headers)
- self.assertEqual(res.read(), b'%d %d' % (size, size) +
self.linesep)
-
- def test_large_content_length_truncated(self):
- for w in range(18, 65):
- size = 1 << w
- headers = {'Content-Length' : str(size)}
- res = self.request('/cgi-bin/file1.py', 'POST', b'x', headers)
- self.assertEqual(res.read(), b'Hello World' + self.linesep)
-
def test_invaliduri(self):
res = self.request('/cgi-bin/invalid')
res.read()
diff --git
a/Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst
b/Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst
deleted file mode 100644
index 98956627f2b30d..00000000000000
--- a/Misc/NEWS.d/next/Security/2024-05-23-11-44-41.gh-issue-119452.PRfsSv.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Fix a potential memory denial of service in the :mod:`http.server` module.
-When a malicious user is connected to the CGI server on Windows, it could cause
-an arbitrary amount of memory to be allocated.
-This could have led to symptoms including a :exc:`MemoryError`, swapping, out
-of memory (OOM) killed processes or containers, or even system crashes.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]