Browse files

Fix reponse header sanitization.

  • Loading branch information...
1 parent 15798a1 commit 1ae91f6d58e6257e0ab49d295d8741ce1727bdb7 @bdarnell bdarnell committed Apr 23, 2012
Showing with 16 additions and 1 deletion.
  1. +15 −0 tornado/test/web_test.py
  2. +1 −1 tornado/web.py
View
15 tornado/test/web_test.py
@@ -335,6 +335,16 @@ def get(self):
raise Exception("didn't get permanent or status arguments")
+class HeaderInjectionHandler(RequestHandler):
+ def get(self):
+ try:
+ self.set_header("X-Foo", "foo\r\nX-Bar: baz")
+ raise Exception("Didn't get expected exception")
+ except ValueError, e:
+ assert "Unsafe header value" in str(e)
+ self.finish(b("ok"))
+
+
class WebTest(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
loader = DictLoader({
@@ -359,6 +369,7 @@ def get_app(self):
url("/flow_control", FlowControlHandler),
url("/multi_header", MultiHeaderHandler),
url("/redirect", RedirectHandler),
+ url("/header_injection", HeaderInjectionHandler),
]
return Application(urls,
template_loader=loader,
@@ -452,6 +463,10 @@ def test_redirect(self):
response = self.fetch("/redirect?status=307", follow_redirects=False)
self.assertEqual(response.code, 307)
+ def test_header_injection(self):
+ response = self.fetch("/header_injection")
+ self.assertEqual(response.body, b("ok"))
+
class ErrorResponseTest(AsyncHTTPTestCase, LogTrapTestCase):
def get_app(self):
View
2 tornado/web.py
@@ -275,7 +275,7 @@ def _convert_header_value(self, value):
# If \n is allowed into the header, it is possible to inject
# additional headers or split the request. Also cap length to
# prevent obviously erroneous values.
- if len(value) > 4000 or re.match(b(r"[\x00-\x1f]"), value):
+ if len(value) > 4000 or re.search(b(r"[\x00-\x1f]"), value):
raise ValueError("Unsafe header value %r", value)
return value

0 comments on commit 1ae91f6

Please sign in to comment.