]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-103204: `http.server` - Enforce that HTTP version numbers must consist only of...
authorBen Kallus <49924171+kenballus@users.noreply.github.com>
Fri, 12 May 2023 20:25:58 +0000 (16:25 -0400)
committerGitHub <noreply@github.com>
Fri, 12 May 2023 20:25:58 +0000 (13:25 -0700)
Reject HTTP requests with invalid http/x.y version numbers: x or y being non-digits or too-long.

---------

Co-authored-by: Oleg Iarygin <oleg@arhadthedev.net>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Lib/http/server.py
Lib/test/test_httpservers.py
Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst [new file with mode: 0644]

index a245ffb307860aaf8b6db6f7c0636cb95d6a0257..ca6240d9a921e66863d5a91f1cf130f9b4c95d76 100644 (file)
@@ -300,6 +300,10 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
                 #   - Leading zeros MUST be ignored by recipients.
                 if len(version_number) != 2:
                     raise ValueError
+                if any(not component.isdigit() for component in version_number):
+                    raise ValueError("non digit in http version")
+                if any(len(component) > 10 for component in version_number):
+                    raise ValueError("unreasonable length http version")
                 version_number = int(version_number[0]), int(version_number[1])
             except (ValueError, IndexError):
                 self.send_error(
index 0382b5ec448d57fd1a0475673aab9b7c5e7a8fdb..cdd1bea754a020178cf667f1903e7ffe95a5485d 100644 (file)
@@ -164,6 +164,27 @@ class BaseHTTPServerTestCase(BaseTestCase):
         res = self.con.getresponse()
         self.assertEqual(res.status, HTTPStatus.BAD_REQUEST)
 
+    def test_version_signs_and_underscores(self):
+        self.con._http_vsn_str = 'HTTP/-9_9_9.+9_9_9'
+        self.con.putrequest('GET', '/')
+        self.con.endheaders()
+        res = self.con.getresponse()
+        self.assertEqual(res.status, HTTPStatus.BAD_REQUEST)
+
+    def test_major_version_number_too_long(self):
+        self.con._http_vsn_str = 'HTTP/909876543210.0'
+        self.con.putrequest('GET', '/')
+        self.con.endheaders()
+        res = self.con.getresponse()
+        self.assertEqual(res.status, HTTPStatus.BAD_REQUEST)
+
+    def test_minor_version_number_too_long(self):
+        self.con._http_vsn_str = 'HTTP/1.909876543210'
+        self.con.putrequest('GET', '/')
+        self.con.endheaders()
+        res = self.con.getresponse()
+        self.assertEqual(res.status, HTTPStatus.BAD_REQUEST)
+
     def test_version_none_get(self):
         self.con._http_vsn_str = ''
         self.con.putrequest('GET', '/')
diff --git a/Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst b/Misc/NEWS.d/next/Library/2023-04-02-23-05-22.gh-issue-103204.bbDmu0.rst
new file mode 100644 (file)
index 0000000..f8b3aa5
--- /dev/null
@@ -0,0 +1,3 @@
+Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers
+preceded by '+', or '-', or with digit-separating '_' characters.  The length
+of the version numbers is also constrained.