summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDinesh <dineshthumma15@gmail.com>2026-03-21 22:51:11 +0530
committerJacob Walls <jacobtylerwalls@gmail.com>2026-04-22 14:25:08 -0400
commitdc467fdc3b5744cec71fab876c23a14013e2510b (patch)
tree5702150cc3838f3e97af78599614f257ea950cf0
parente1bdebc84ee7cacd40b820e862fd504054619403 (diff)
Fixed #36991 -- Raised BadRequest for invalid encodings in Content-Type headers.
-rw-r--r--django/http/request.py9
-rw-r--r--django/utils/http.py6
-rw-r--r--tests/requests_tests/tests.py14
-rw-r--r--tests/utils_tests/test_http.py14
4 files changed, 39 insertions, 4 deletions
diff --git a/django/http/request.py b/django/http/request.py
index f871ea15e8..44bf09450b 100644
--- a/django/http/request.py
+++ b/django/http/request.py
@@ -155,9 +155,12 @@ class HttpRequest:
def _set_content_type_params(self, meta):
"""Set content_type, content_params, and encoding."""
- self.content_type, self.content_params = parse_header_parameters(
- meta.get("CONTENT_TYPE", "")
- )
+ try:
+ self.content_type, self.content_params = parse_header_parameters(
+ meta.get("CONTENT_TYPE", "")
+ )
+ except ValueError as exc:
+ raise BadRequest("Invalid Content-Type header.") from exc
if "charset" in self.content_params:
try:
codecs.lookup(self.content_params["charset"])
diff --git a/django/utils/http.py b/django/utils/http.py
index f72f54e958..f6cce96206 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -366,7 +366,11 @@ def parse_header_parameters(line, max_length=MAX_HEADER_LENGTH):
value = value.replace("\\\\", "\\").replace('\\"', '"')
if has_encoding:
encoding, lang, value = value.split("'")
- value = unquote(value, encoding=encoding)
+ try:
+ value = unquote(value, encoding=encoding)
+ except (LookupError, UnicodeDecodeError):
+ msg = f"Invalid encoding {encoding!r} for RFC 2231 param."
+ raise ValueError(msg)
pdict[name] = value
return key, pdict
diff --git a/tests/requests_tests/tests.py b/tests/requests_tests/tests.py
index b15d954cb3..c25dd913cf 100644
--- a/tests/requests_tests/tests.py
+++ b/tests/requests_tests/tests.py
@@ -456,6 +456,20 @@ class RequestsTests(SimpleTestCase):
with self.assertRaises(RawPostDataException):
request.body
+ def test_malformed_header(self):
+ tests = [
+ # Invalid encoding name with percent-encoded value
+ "text/plain; charset*=BOGUS''%20",
+ # Another invalid encoding with different value
+ "text/plain; filename*=INVALID''%s%s%s",
+ # Invalid encoding with multi-line encoded content
+ "text/plain; title*=NOTACODEC''%E2%80%A6",
+ ]
+ msg = "Invalid Content-Type header."
+ for header in tests:
+ with self.subTest(header=header), self.assertRaisesMessage(BadRequest, msg):
+ WSGIRequest({"REQUEST_METHOD": "GET", "CONTENT_TYPE": header})
+
def test_malformed_multipart_header(self):
tests = [
('Content-Disposition : form-data; name="name"', {"name": ["value"]}),
diff --git a/tests/utils_tests/test_http.py b/tests/utils_tests/test_http.py
index 58a4b40f3e..f18deb7c70 100644
--- a/tests/utils_tests/test_http.py
+++ b/tests/utils_tests/test_http.py
@@ -521,6 +521,20 @@ class ParseHeaderParameterTests(unittest.TestCase):
parsed = parse_header_parameters(raw_line)
self.assertEqual(parsed[1]["title"], expected_title)
+ def test_rfc2231_invalid_encoding(self):
+ test_data = [
+ # Invalid encoding name with percent-encoded value
+ "text/plain; charset*=BOGUS''%20",
+ # Another invalid encoding with different value
+ "text/plain; filename*=INVALID''%s%s%s",
+ # Invalid encoding with multi-line encoded content
+ "text/plain; title*=NOTACODEC''%E2%80%A6",
+ ]
+ msg = "Invalid encoding"
+ for header in test_data:
+ with self.subTest(raw_line=header), self.assertRaisesRegex(ValueError, msg):
+ parse_header_parameters(header)
+
def test_header_max_length(self):
base_header = "Content-Type: application/x-stuff; title*="
base_header_len = len(base_header)