]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Allow horizontal tabs in header values
authorDave Shawley <daves@aweber.com>
Wed, 18 Dec 2024 18:30:37 +0000 (13:30 -0500)
committerDave Shawley <daveshawley@gmail.com>
Fri, 27 Dec 2024 22:10:59 +0000 (17:10 -0500)
Addresses: https://github.com/tornadoweb/tornado/issues/3450

tornado/test/web_test.py
tornado/web.py

index a829657abe66e6ddabc8621cb4b1b7a87995dfc8..9c6d750f887a992278bf81a6607431f8eb4d6262 100644 (file)
@@ -706,6 +706,23 @@ class HeaderInjectionHandler(RequestHandler):
                 raise
 
 
+class SetHeaderHandler(RequestHandler):
+    def get(self):
+        # tests the validity of web.RequestHandler._INVALID_HEADER_CHAR_RE
+        # should match the invalid characters from
+        # https://www.rfc-editor.org/rfc/rfc9110#name-field-values
+        illegal_chars = [chr(o) for o in range(0, 0x20)]
+        illegal_chars.remove('\t')
+        for char in illegal_chars:
+            try:
+                self.set_header("X-Foo", "foo" + char + "bar")
+                raise Exception("Didn't get expected exception")
+            except ValueError as e:
+                if "Unsafe header value" not in str(e):
+                    raise
+        self.finish(b"ok")
+
+
 class GetArgumentHandler(RequestHandler):
     def prepare(self):
         if self.get_argument("source", None) == "query":
@@ -790,6 +807,7 @@ class WSGISafeWebTest(WebTestCase):
             url("/header_injection", HeaderInjectionHandler),
             url("/get_argument", GetArgumentHandler),
             url("/get_arguments", GetArgumentsHandler),
+            url("/set_header", SetHeaderHandler),
         ]
         return urls
 
@@ -938,6 +956,10 @@ js_embed()
         response = self.fetch("/header_injection")
         self.assertEqual(response.body, b"ok")
 
+    def test_set_header(self):
+        response = self.fetch("/set_header")
+        self.assertEqual(response.body, b"ok")
+
     def test_get_argument(self):
         response = self.fetch("/get_argument?foo=bar")
         self.assertEqual(response.body, b"bar")
index 357c5f1aefd147bd89ddc7be519890faa7ab4899..acaae7ded74c0e643e31cfd66295ecebd591cf36 100644 (file)
@@ -399,7 +399,7 @@ class RequestHandler:
         if name in self._headers:
             del self._headers[name]
 
-    _INVALID_HEADER_CHAR_RE = re.compile(r"[\x00-\x1f]")
+    _INVALID_HEADER_CHAR_RE = re.compile(r"[\x00-\x08\x0a-\x1f]")
 
     def _convert_header_value(self, value: _HeaderTypes) -> str:
         # Convert the input value to a str. This type check is a bit