Skip to content

Commit

Permalink
Check header names and status for line feed/carriage return. Fixes #122
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Mar 19, 2016
1 parent 7b9c4b3 commit 4deab9f
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 4 deletions.
9 changes: 5 additions & 4 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
See: https://github.com/Pylons/waitress/pull/82 and
https://github.com/Pylons/waitress/issues/76

- 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.
- Waitress will no longer accept headers or status lines 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
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,5 @@ Contributors
- Bert JW Regeer, 2015-09-23

- Yu Zhou, 2015-09-24

- Jason Madden, 2016-03-19
7 changes: 7 additions & 0 deletions waitress/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,9 @@ def start_response(status, headers, exc_info=None):

if not status.__class__ is str:
raise AssertionError('status %s is not a string' % status)
if '\n' in status or '\r' in status:
raise ValueError("carriage return/line "
"feed character present in status")

self.status = status

Expand All @@ -375,6 +378,10 @@ def start_response(status, headers, exc_info=None):
if '\n' in v or '\r' in v:
raise ValueError("carriage return/line "
"feed character present in header value")
if '\n' in k or '\r' in k:
raise ValueError("carriage return/line "
"feed character present in header name")

kl = k.lower()
if kl == 'content-length':
self.content_length = int(v)
Expand Down
14 changes: 14 additions & 0 deletions waitress/tests/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,20 @@ def app(environ, start_response):
inst.channel.server.application = app
self.assertRaises(ValueError, inst.execute)

def test_execute_bad_header_name_control_characters(self):
def app(environ, start_response):
start_response('200 OK', [('a\r', 'value')])
inst = self._makeOne()
inst.channel.server.application = app
self.assertRaises(ValueError, inst.execute)

def test_execute_bad_status_control_characters(self):
def app(environ, start_response):
start_response('200 OK\r', [])
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')])
Expand Down

0 comments on commit 4deab9f

Please sign in to comment.