]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.10] gh-144370: Disallow usage of control characters in status in wsgiref.handlers... 3.10
authorVictor Stinner <vstinner@python.org>
Sun, 17 May 2026 18:33:20 +0000 (20:33 +0200)
committerGitHub <noreply@github.com>
Sun, 17 May 2026 18:33:20 +0000 (11:33 -0700)
Lib/test/test_wsgiref.py
Lib/wsgiref/handlers.py
Misc/ACKS
Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst [new file with mode: 0644]

index 7c6c72f6e81384ffbef6f8a408b8803283f0681d..a2b07f6aa345d7bfa6b0433f48be8af06e325328 100644 (file)
@@ -879,6 +879,25 @@ class HandlerTests(TestCase):
         self.assertIsNotNone(h.status)
         self.assertIsNotNone(h.environ)
 
+    def testRaisesControlCharacters(self):
+        for c0 in control_characters_c0():
+            with self.subTest(c0):
+                base = BaseHandler()
+                with self.assertRaises(ValueError):
+                    base.start_response(c0, [('x', 'y')])
+
+                base = BaseHandler()
+                with self.assertRaises(ValueError):
+                    base.start_response('200 OK', [(c0, 'y')])
+
+                # HTAB (\x09) is allowed in header values, but not in names.
+                base = BaseHandler()
+                if c0 != "\t":
+                    with self.assertRaises(ValueError):
+                        base.start_response('200 OK', [('x', c0)])
+                else:
+                    base.start_response('200 OK', [('x', c0)])
+
 
 if __name__ == "__main__":
     unittest.main()
index 31360e58785ac6e824a339d2005ac1d0d5087df7..df30af39293d2ca39d531b542afc2efcc41be358 100644 (file)
@@ -1,7 +1,7 @@
 """Base classes for server/gateway implementations"""
 
 from .util import FileWrapper, guess_scheme, is_hop_by_hop
-from .headers import Headers
+from .headers import Headers, _name_disallowed_re
 
 import sys, os, time
 
@@ -238,6 +238,8 @@ class BaseHandler:
         self.status = status
         self.headers = self.headers_class(headers)
         status = self._convert_string_type(status, "Status")
+        if _name_disallowed_re.search(status):
+            raise ValueError("Control characters are not allowed in status")
         assert len(status)>=4,"Status must be at least 4 characters"
         assert status[:3].isdigit(), "Status message must begin w/3-digit code"
         assert status[3]==" ", "Status message must have a space after code"
index 8483e1105088895ea1e4cb38e834c8d28dd17308..9c28337a4b4343ebc35e1442af3be192fc850bbc 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1006,6 +1006,7 @@ Wolfgang Langner
 Detlef Lannert
 RĂ©mi Lapeyre
 Soren Larsen
+Seth Michael Larson
 Amos Latteier
 Piers Lauder
 Ben Laurie
diff --git a/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst b/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst
new file mode 100644 (file)
index 0000000..2d13a06
--- /dev/null
@@ -0,0 +1,2 @@
+Disallow usage of control characters in status in :mod:`wsgiref.handlers` to prevent HTTP header injections.
+Patch by Benedikt Johannes.