diff options
author | Bert JW Regeer <xistence@0x58.com> | 2016-01-03 00:48:53 -0700 |
---|---|---|
committer | Bert JW Regeer <xistence@0x58.com> | 2016-01-03 00:48:53 -0700 |
commit | 7210c6048770d90089219db553eb968c64a60b42 (patch) | |
tree | e6d90dcb3b4aac4b7caa8b58ff5ab09e04ba043b | |
parent | 31fa39641ec259a61eb344d493470533f6ff0071 (diff) | |
parent | 260b9daecbffdb61aca06b35213234f21acfbf5d (diff) | |
download | waitress-7210c6048770d90089219db553eb968c64a60b42.tar.gz |
Merge pull request #121 from Pylons/feature/header_seatbelt
Disallow control characters (\n\r) in start_response's headers
-rw-r--r-- | CHANGES.txt | 5 | ||||
-rw-r--r-- | waitress/task.py | 4 | ||||
-rw-r--r-- | waitress/tests/test_task.py | 7 |
3 files changed, 16 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index 4f50e50..71e4567 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,11 @@ Next release ------------ +- Waitress will no longer accept headers with newline/carriage returns in them, + thereby disallowing HTTP Response Splitting. See + https://github.com/Pylons/waitress/issues/117 for more information, as well + as https://www.owasp.org/index.php/HTTP_Response_Splitting. + - Call prune() on the output buffer at the end of a request so that it doesn't continue to grow without bounds. See https://github.com/Pylons/waitress/issues/111 for more information. diff --git a/waitress/task.py b/waitress/task.py index 7136c32..501547a 100644 --- a/waitress/task.py +++ b/waitress/task.py @@ -371,6 +371,10 @@ class WSGITask(Task): raise AssertionError( 'Header value %r is not a string in %r' % (v, (k, v)) ) + + if '\n' in v or '\r' in v: + raise ValueError("carriage return/line " + "feed character present in header value") kl = k.lower() if kl == 'content-length': self.content_length = int(v) diff --git a/waitress/tests/test_task.py b/waitress/tests/test_task.py index 6d6fcce..c836f69 100644 --- a/waitress/tests/test_task.py +++ b/waitress/tests/test_task.py @@ -409,6 +409,13 @@ class TestWSGITask(unittest.TestCase): inst.channel.server.application = app self.assertRaises(AssertionError, inst.execute) + def test_execute_bad_header_value_control_characters(self): + def app(environ, start_response): + start_response('200 OK', [('a', '\n')]) + inst = self._makeOne() + inst.channel.server.application = app + self.assertRaises(ValueError, inst.execute) + def test_preserve_header_value_order(self): def app(environ, start_response): write = start_response('200 OK', [('C', 'b'), ('A', 'b'), ('A', 'a')]) |