]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
httputil: Reject header lines beginning with invalid whitespace 3488/head
authorBen Darnell <ben@bendarnell.com>
Fri, 25 Apr 2025 19:31:13 +0000 (15:31 -0400)
committerBen Darnell <ben@bendarnell.com>
Fri, 25 Apr 2025 19:40:08 +0000 (15:40 -0400)
The obs-fold feature is defined only for tabs and spaces.
The str.isspace() method also accepts other whitespace characters.
These characters are not valid in HTTP headers and should be treated
as errors instead of triggering line folding.

Fixes #3480

tornado/httputil.py
tornado/test/httputil_test.py

index 0f443cddc4c58ccb75b1d6025fa24e17cbc67585..5d05cacbd81792cc09e46cee4e029fa8152f51ad 100644 (file)
@@ -248,7 +248,7 @@ class HTTPHeaders(StrMutableMapping):
         if not line:
             # Empty line, or the final CRLF of a header block.
             return
-        if line[0].isspace():
+        if line[0] in HTTP_WHITESPACE:
             # continuation of a multi-line header
             # TODO(7.0): Remove support for line folding.
             if self._last_key is None:
index 53ae46076fcb943f7717a9cdf6db1f8f8a42cb90..221c1dcb46d4672cfd69b00e1809a955ba24f798 100644 (file)
@@ -287,13 +287,22 @@ Foo: even
             [("Asdf", "qwer zxcv"), ("Foo", "bar baz"), ("Foo", "even more lines")],
         )
 
-    def test_malformed_continuation(self):
+    def test_continuation(self):
+        data = "Foo: bar\r\n\tasdf"
+        headers = HTTPHeaders.parse(data)
+        self.assertEqual(headers["Foo"], "bar asdf")
+
         # If the first line starts with whitespace, it's a
         # continuation line with nothing to continue, so reject it
         # (with a proper error).
         data = " Foo: bar"
         self.assertRaises(HTTPInputError, HTTPHeaders.parse, data)
 
+        # \f (formfeed) is whitespace according to str.isspace, but
+        # not according to the HTTP spec.
+        data = "Foo: bar\r\n\fasdf"
+        self.assertRaises(HTTPInputError, HTTPHeaders.parse, data)
+
     def test_unicode_newlines(self):
         # Ensure that only \r\n is recognized as a header separator, and not
         # the other newline-like unicode characters.