Skip to content

Commit

Permalink
Allow horizontal tabs in header values
Browse files Browse the repository at this point in the history
Addresses: tornadoweb#3450
  • Loading branch information
dave-shawley committed Dec 27, 2024
1 parent 0a39ba8 commit de7f0e4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
22 changes: 22 additions & 0 deletions tornado/test/web_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,23 @@ def get(self):
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":
Expand Down Expand Up @@ -790,6 +807,7 @@ def get_handlers(self):
url("/header_injection", HeaderInjectionHandler),
url("/get_argument", GetArgumentHandler),
url("/get_arguments", GetArgumentsHandler),
url("/set_header", SetHeaderHandler),
]
return urls

Expand Down Expand Up @@ -938,6 +956,10 @@ def test_header_injection(self):
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")
Expand Down
2 changes: 1 addition & 1 deletion tornado/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def clear_header(self, name: str) -> None:
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
Expand Down

0 comments on commit de7f0e4

Please sign in to comment.