Skip to content

Commit

Permalink
Merge pull request #229 from Pylons/feature/header_seatbelt
Browse files Browse the repository at this point in the history
Add extra security checks for HTTP Headers

Avoid HTTP Response Splitting.
  • Loading branch information
digitalresistor committed Jan 3, 2016
2 parents 87a1254 + c380216 commit 97041f5
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
8 changes: 8 additions & 0 deletions tests/test_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,14 @@ def test_header_getter_fset_text():
desc.fset(resp, text_('avalue'))
eq_(desc.fget(resp), 'avalue')

def test_header_getter_fset_text_control_chars():
from webob.compat import text_
from webob.descriptors import header_getter
from webob import Response
resp = Response('aresp')
desc = header_getter('AHEADER', '14.3')
assert_raises(ValueError, desc.fset, resp, text_('\n'))

def test_header_getter_fdel():
from webob.descriptors import header_getter
from webob import Response
Expand Down
11 changes: 11 additions & 0 deletions tests/test_exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,17 @@ def start_response(status, headers, exc_info=None):
m = webob_exc._HTTPMove(location='http://example.com')
assert_equal( m( environ, start_response ), [] )

def test_HTTPMove_location_newlines():
environ = {
'wsgi.url_scheme': 'HTTP',
'SERVER_NAME': 'localhost',
'SERVER_PORT': '80',
'REQUEST_METHOD': 'HEAD',
'PATH_INFO': '/',
}
assert_raises(ValueError, webob_exc._HTTPMove,
location='http://example.com\r\nX-Test: false')

def test_HTTPMove_add_slash_and_location():
def start_response(status, headers, exc_info=None):
pass
Expand Down
3 changes: 3 additions & 0 deletions webob/descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ def fget(r):
def fset(r, value):
fdel(r)
if value is not None:
if '\n' in value or '\r' in value:
raise ValueError('Header value may not contain control characters')

if isinstance(value, text_type) and not PY3:
value = value.encode('latin-1')
r._headerlist.append((header, value))
Expand Down
3 changes: 3 additions & 0 deletions webob/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,9 @@ def __init__(self, detail=None, headers=None, comment=None,
detail=detail, headers=headers, comment=comment,
body_template=body_template)
if location is not None:
if '\n' in location or '\r' in location:
raise ValueError('Control characters are not allowed in location')

self.location = location
if add_slash:
raise TypeError(
Expand Down

0 comments on commit 97041f5

Please sign in to comment.