diff --git a/django/http/__init__.py b/django/http/__init__.py index 7c6b8f9a0ff..92c38c0ad6b 100644 --- a/django/http/__init__.py +++ b/django/http/__init__.py @@ -263,6 +263,9 @@ def parse_cookie(cookie): cookiedict[key] = c.get(key).value return cookiedict +class BadHeaderError(ValueError): + pass + class HttpResponse(object): """A basic HTTP response, with content and dictionary-accessed headers.""" @@ -301,6 +304,8 @@ class HttpResponse(object): def _convert_to_ascii(self, *values): """Converts all values to ascii strings.""" for value in values: + if '\n' in value or '\r' in value: + raise BadHeaderError("Header values can't contain newlines (got %r)" % (value)) if isinstance(value, unicode): try: yield value.encode('us-ascii') diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 6b29b3bb619..8701c762357 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -445,6 +445,11 @@ To set a header in your response, just treat it like a dictionary:: >>> response = HttpResponse() >>> response['Pragma'] = 'no-cache' +.. versionadded:: 1.1 + +HTTP headers cannot contain newlines. An attempt to set a header containing a +newline character (CR or LF) will raise ``BadHeaderError`` + Telling the browser to treat the response as a file attachment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py index 15b872821c1..04099be16ee 100644 --- a/tests/regressiontests/httpwrappers/tests.py +++ b/tests/regressiontests/httpwrappers/tests.py @@ -444,6 +444,17 @@ Traceback (most recent call last): ... UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format +# Bug #10188: Do not allow newlines in headers (CR or LF) +>>> r['test\\rstr'] = 'test' +Traceback (most recent call last): +... +BadHeaderError: Header values can't contain newlines (got 'test\\rstr') + +>>> r['test\\nstr'] = 'test' +Traceback (most recent call last): +... +BadHeaderError: Header values can't contain newlines (got 'test\\nstr') + # # Regression test for #8278: QueryDict.update(QueryDict) #