diff options
| author | Tim Harris <timharris@Tims-MacBook-Air-2.local> | 2026-05-18 17:06:06 -0700 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-05-27 11:41:48 -0400 |
| commit | 6e15ac8066312328de279e3e072667416c205bfc (patch) | |
| tree | b946a9c743a450a88d90f09b60e9390ac4cef053 | |
| parent | 7ae70e7504b98553ab3537be84f930ea7e28c3c9 (diff) | |
Fixed #36905 -- Deprecated the safe parameter of JSONResponse.
Peer frameworks have long since dropped their analogous checks for this
vulnerability that was fixed in ES5.
| -rw-r--r-- | django/http/response.py | 17 | ||||
| -rw-r--r-- | docs/ref/request-response.txt | 8 | ||||
| -rw-r--r-- | docs/releases/6.2.txt | 8 | ||||
| -rw-r--r-- | tests/httpwrappers/tests.py | 25 |
4 files changed, 46 insertions, 12 deletions
diff --git a/django/http/response.py b/django/http/response.py index 12cf47b1c1..3b948d6eed 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -20,6 +20,10 @@ from django.core.serializers.json import DjangoJSONEncoder from django.http.cookie import SimpleCookie from django.utils import timezone from django.utils.datastructures import CaseInsensitiveMapping +from django.utils.deprecation import ( + RemovedInDjango71Warning, + django_file_prefixes, +) from django.utils.encoding import iri_to_uri from django.utils.functional import cached_property from django.utils.http import ( @@ -755,10 +759,21 @@ class JsonResponse(HttpResponse): self, data, encoder=DjangoJSONEncoder, - safe=True, + # RemovedInDjango71Warning: Remove the safe parameter. + safe=None, json_dumps_params=None, **kwargs, ): + # RemovedInDjango71Warning. + if safe is None: + safe = False + else: + warnings.warn( + "The safe parameter is deprecated.", + category=RemovedInDjango71Warning, + skip_file_prefixes=django_file_prefixes(), + ) + # RemovedInDjango71Warning. if safe and not isinstance(data, dict): raise TypeError( "In order to allow non-dict objects to be serialized set the " diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index 906da679c7..eebd0cd053 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -1281,6 +1281,14 @@ using non-dict objects in JSON-encoded response. modern browsers implement ECMAScript 5 which removes this attack vector. Therefore it is possible to disable this security precaution. +.. versionchanged:: 6.2 + + In earlier versions, the ``safe`` parameter defaulted to ``True``. + +.. deprecated:: 6.2 + + The ``safe`` parameter is deprecated. + Changing the default JSON encoder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/releases/6.2.txt b/docs/releases/6.2.txt index ba9396313d..1193f7a84d 100644 --- a/docs/releases/6.2.txt +++ b/docs/releases/6.2.txt @@ -251,7 +251,10 @@ backends. Miscellaneous ------------- -* ... +* To facilitate the deprecation of the ``safe`` parameter of + :class:`~django.http.JsonResponse`, it now defaults to ``False``, because the + pollution vulnerability in the ``Array`` prototype was fixed in + `ES5 <https://262.ecma-international.org/5.1/#sec-11.1.4>`_. .. _deprecated-features-6.2: @@ -261,4 +264,5 @@ Features deprecated in 6.2 Miscellaneous ------------- -* ... +* The ``safe`` parameter is deprecated from :class:`~django.http.JsonResponse`. + Omitting the argument is equivalent to the prior ``safe=False`` usage. diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index 151088909c..e2eb9af30f 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -24,6 +24,7 @@ from django.http import ( parse_cookie, ) from django.test import SimpleTestCase +from django.utils.deprecation import RemovedInDjango71Warning from django.utils.encoding import iri_to_uri from django.utils.functional import lazystr from django.utils.http import MAX_URL_REDIRECT_LENGTH @@ -703,25 +704,31 @@ class JsonResponseTests(SimpleTestCase): response = JsonResponse(data) self.assertEqual(json.loads(response.text), data) - def test_json_response_raises_type_error_with_default_setting(self): - with self.assertRaisesMessage( - TypeError, - "In order to allow non-dict objects to be serialized set the " - "safe parameter to False", + # RemovedInDjango71Warning: When the deprecation ends, remove this test. + def test_json_response_raises_type_error_with_safe_arg(self): + with ( + self.assertRaisesMessage( + TypeError, + "In order to allow non-dict objects to be serialized set the " + "safe parameter to False", + ), + self.assertWarnsMessage( + RemovedInDjango71Warning, "The safe parameter is deprecated." + ), ): - JsonResponse([1, 2, 3]) + JsonResponse([1, 2, 3], safe=True) def test_json_response_text(self): - response = JsonResponse("foobar", safe=False) + response = JsonResponse("foobar") self.assertEqual(json.loads(response.text), "foobar") def test_json_response_list(self): - response = JsonResponse(["foo", "bar"], safe=False) + response = JsonResponse(["foo", "bar"]) self.assertEqual(json.loads(response.text), ["foo", "bar"]) def test_json_response_uuid(self): u = uuid.uuid4() - response = JsonResponse(u, safe=False) + response = JsonResponse(u) self.assertEqual(json.loads(response.text), str(u)) def test_json_response_custom_encoder(self): |
