check if the header contains control characters

fix #1227
This commit is contained in:
benoitc 2016-03-18 23:15:26 +01:00
parent 52088be726
commit 1e10a02e73
2 changed files with 29 additions and 0 deletions

View File

@ -10,6 +10,8 @@ import re
import sys
from gunicorn._compat import unquote_to_wsgi_str
from gunicorn.http.message import HEADER_RE
from gunicorn.http.errors import InvalidHeader, InvalidHeaderName
from gunicorn.six import string_types, binary_type, reraise
from gunicorn import SERVER_SOFTWARE
import gunicorn.util as util
@ -28,6 +30,7 @@ except ImportError:
BLKSIZE = 0x3FFFFFFF
NORMALIZE_SPACE = re.compile(r'(?:\r\n)?[ \t]+')
HEADER_VALUE_RE = re.compile(r'[\x00-\x1F\x7F]')
log = logging.getLogger(__name__)
@ -264,6 +267,13 @@ class Response(object):
for name, value in headers:
if not isinstance(name, string_types):
raise TypeError('%r is not a string' % name)
if HEADER_RE.search(name):
raise InvalidHeaderName('%r' % name)
if HEADER_VALUE_RE.search(value):
raise InvalidHeader('%r' % value)
value = str(value).strip()
lname = name.lower().strip()
if lname == "content-length":

View File

@ -1,10 +1,12 @@
# -*- encoding: utf-8 -*-
import t
import pytest
from gunicorn import util
from gunicorn.http.body import Body
from gunicorn.http.wsgi import Response
from gunicorn.six import BytesIO
from gunicorn.http.errors import InvalidHeader, InvalidHeaderName
try:
import unittest.mock as mock
@ -94,3 +96,20 @@ def test_http_header_encoding():
mocked_socket.sendall(util.to_bytestring(header_str,"ascii"))
except Exception as e:
assert isinstance(e, UnicodeEncodeError)
def test_http_inalid_response_header():
""" tests whether http response headers are contains control chars """
mocked_socket = mock.MagicMock()
mocked_socket.sendall = mock.MagicMock()
mocked_request = mock.MagicMock()
response = Response(mocked_request, mocked_socket, None)
with pytest.raises(InvalidHeader):
response.start_response("200 OK", [('foo', 'essai\r\n')])
response = Response(mocked_request, mocked_socket, None)
with pytest.raises(InvalidHeaderName):
response.start_response("200 OK", [('foo\r\n', 'essai')])