From: Victor Stinner Date: Sun, 17 May 2026 18:33:20 +0000 (+0200) Subject: [3.10] gh-144370: Disallow usage of control characters in status in wsgiref.handlers... X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=10cf7e2bf76171f7c3b050a9acd762320e00486b;p=thirdparty%2FPython%2Fcpython.git [3.10] gh-144370: Disallow usage of control characters in status in wsgiref.handlers for security (#144371) (#145673) --- diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 7c6c72f6e813..a2b07f6aa345 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -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() diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 31360e58785a..df30af39293d 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -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" diff --git a/Misc/ACKS b/Misc/ACKS index 8483e1105088..9c28337a4b43 100644 --- 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 index 000000000000..2d13a0611322 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-01-31-21-56-54.gh-issue-144370.fp9m8t.rst @@ -0,0 +1,2 @@ +Disallow usage of control characters in status in :mod:`wsgiref.handlers` to prevent HTTP header injections. +Patch by Benedikt Johannes.