Skip to content

Commit 5364575

Browse files
varunkasyapjacobtylerwalls
authored andcommitted
Fixed #37100 -- Prevented control characters in HttpResponse reason_phrase.
1 parent bc9bed5 commit 5364575

2 files changed

Lines changed: 19 additions & 2 deletions

File tree

django/http/response.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
_charset_from_content_type_re = _lazy_re_compile(
3333
r";\s*charset=(?P<charset>[^\s;]+)", re.I
3434
)
35+
_control_chars_re = _lazy_re_compile(r"[\x00-\x1f\x7f-\x9f]")
3536

3637

3738
class ResponseHeaders(CaseInsensitiveMapping):
@@ -142,7 +143,7 @@ def __init__(
142143

143144
if not 100 <= self.status_code <= 599:
144145
raise ValueError("HTTP status code must be an integer from 100 to 599.")
145-
self._reason_phrase = reason
146+
self.reason_phrase = reason
146147

147148
@property
148149
def reason_phrase(self):
@@ -154,6 +155,8 @@ def reason_phrase(self):
154155

155156
@reason_phrase.setter
156157
def reason_phrase(self, value):
158+
if value and _control_chars_re.search(value):
159+
raise BadHeaderError("reason_phrase can't contain control characters.")
157160
self._reason_phrase = value
158161

159162
@property

tests/responses/tests.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from django.conf import settings
44
from django.core.cache import cache
5-
from django.http import HttpResponse
5+
from django.http import BadHeaderError, HttpResponse
66
from django.http.response import HttpResponseBase
77
from django.test import SimpleTestCase
88

@@ -103,6 +103,20 @@ def test_reason_phrase(self):
103103
self.assertEqual(resp.status_code, 419)
104104
self.assertEqual(resp.reason_phrase, reason)
105105

106+
def test_invalid_reason_phrase(self):
107+
msg = "reason_phrase can't contain control characters."
108+
invalid_reasons = [
109+
"OK\r\nX-Injected-header: yes",
110+
"OK\x00",
111+
"OK\x1f",
112+
"OK\x7f",
113+
"OK\x9f",
114+
]
115+
for reason in invalid_reasons:
116+
with self.subTest(reason=reason):
117+
with self.assertRaisesMessage(BadHeaderError, msg):
118+
HttpResponse(reason=reason)
119+
106120
def test_charset_detection(self):
107121
"""HttpResponse should parse charset from content_type."""
108122
response = HttpResponse("ok")

0 commit comments

Comments
 (0)