From: Dave Shawley Date: Wed, 18 Dec 2024 18:30:37 +0000 (-0500) Subject: Allow horizontal tabs in header values X-Git-Tag: v6.5.0b1~19^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=de7f0e4901f728aff6e291c4d243a2099256e451;p=thirdparty%2Ftornado.git Allow horizontal tabs in header values Addresses: https://github.com/tornadoweb/tornado/issues/3450 --- diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py index a829657a..9c6d750f 100644 --- a/tornado/test/web_test.py +++ b/tornado/test/web_test.py @@ -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") diff --git a/tornado/web.py b/tornado/web.py index 357c5f1a..acaae7de 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -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