summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-12 14:43:48 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-01-17 11:49:15 +0100
commitb119f4329c2a4878f1c72f4d25d193d080792f62 (patch)
tree9ce167ad86124abbcd328b73760eb6e6dc288b63
parent23c87874397a22ca80c0d6fa8648fb58ee3ab28a (diff)
Refs #29708 -- Removed PickleSerializer per deprecation timeline.
-rw-r--r--django/contrib/sessions/serializers.py3
-rw-r--r--django/core/serializers/base.py24
-rw-r--r--docs/releases/5.0.txt2
-rw-r--r--docs/topics/http/sessions.txt25
-rw-r--r--tests/defer_regress/tests.py27
-rw-r--r--tests/serializers/tests.py31
6 files changed, 5 insertions, 107 deletions
diff --git a/django/contrib/sessions/serializers.py b/django/contrib/sessions/serializers.py
index f1adf91c22..16a248cc65 100644
--- a/django/contrib/sessions/serializers.py
+++ b/django/contrib/sessions/serializers.py
@@ -1,6 +1,3 @@
-# RemovedInDjango50Warning.
-from django.core.serializers.base import PickleSerializer as BasePickleSerializer
from django.core.signing import JSONSerializer as BaseJSONSerializer
JSONSerializer = BaseJSONSerializer
-PickleSerializer = BasePickleSerializer
diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
index 517d2cad85..20dffac05f 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -1,38 +1,14 @@
"""
Module for abstract serializer/unserializer base classes.
"""
-import pickle
-import warnings
from io import StringIO
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
-from django.utils.deprecation import RemovedInDjango50Warning
DEFER_FIELD = object()
-class PickleSerializer:
- """
- Simple wrapper around pickle to be used in signing.dumps()/loads() and
- cache backends.
- """
-
- def __init__(self, protocol=None):
- warnings.warn(
- "PickleSerializer is deprecated due to its security risk. Use "
- "JSONSerializer instead.",
- RemovedInDjango50Warning,
- )
- self.protocol = pickle.HIGHEST_PROTOCOL if protocol is None else protocol
-
- def dumps(self, obj):
- return pickle.dumps(obj, self.protocol)
-
- def loads(self, data):
- return pickle.loads(data)
-
-
class SerializerDoesNotExist(KeyError):
"""The requested serializer was not found."""
diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt
index fb052b77f1..d39b8d314a 100644
--- a/docs/releases/5.0.txt
+++ b/docs/releases/5.0.txt
@@ -317,3 +317,5 @@ to remove usage of these features.
* The undocumented ability to pass ``errors=None`` to
``SimpleTestCase.assertFormError()`` and ``assertFormsetError()`` is removed.
+
+* ``django.contrib.sessions.serializers.PickleSerializer`` is removed.
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 4dc6f6af35..fd2f106739 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -122,20 +122,6 @@ and the :setting:`SECRET_KEY` setting.
.. warning::
- **If the** ``SECRET_KEY`` **or** ``SECRET_KEY_FALLBACKS`` **are not kept
- secret and you are using the**
- ``django.contrib.sessions.serializers.PickleSerializer``, **this can lead
- to arbitrary remote code execution.**
-
- An attacker in possession of the :setting:`SECRET_KEY` or
- :setting:`SECRET_KEY_FALLBACKS` can not only generate falsified session
- data, which your site will trust, but also remotely execute arbitrary code,
- as the data is serialized using pickle.
-
- If you use cookie-based sessions, pay extra care that your secret key is
- always kept completely secret, for any system which might be remotely
- accessible.
-
**The session data is signed but not encrypted**
When using the cookies backend the session data can be read by the client.
@@ -373,17 +359,6 @@ Bundled serializers
See the :ref:`custom-serializers` section for more details on limitations
of JSON serialization.
-.. class:: serializers.PickleSerializer
-
- Supports arbitrary Python objects, but, as described above, can lead to a
- remote code execution vulnerability if :setting:`SECRET_KEY` or any key of
- :setting:`SECRET_KEY_FALLBACKS` becomes known by an attacker.
-
- .. deprecated:: 4.1
-
- Due to the risk of remote code execution, this serializer is deprecated
- and will be removed in Django 5.0.
-
.. _custom-serializers:
Write your own serializer
diff --git a/tests/defer_regress/tests.py b/tests/defer_regress/tests.py
index 9f94d5fac1..33193e187a 100644
--- a/tests/defer_regress/tests.py
+++ b/tests/defer_regress/tests.py
@@ -1,11 +1,9 @@
from operator import attrgetter
from django.contrib.contenttypes.models import ContentType
-from django.contrib.sessions.backends.db import SessionStore
from django.db import models
from django.db.models import Count
-from django.test import TestCase, ignore_warnings, override_settings
-from django.utils.deprecation import RemovedInDjango50Warning
+from django.test import TestCase
from .models import (
Base,
@@ -106,29 +104,6 @@ class DeferRegressionTest(TestCase):
list(SimpleItem.objects.annotate(Count("feature")).only("name")), list
)
- @ignore_warnings(category=RemovedInDjango50Warning)
- @override_settings(
- SESSION_SERIALIZER="django.contrib.sessions.serializers.PickleSerializer"
- )
- def test_ticket_12163(self):
- # Test for #12163 - Pickling error saving session with unsaved model
- # instances.
- SESSION_KEY = "2b1189a188b44ad18c35e1baac6ceead"
-
- item = Item()
- item._deferred = False
- s = SessionStore(SESSION_KEY)
- s.clear()
- s["item"] = item
- s.save(must_create=True)
-
- s = SessionStore(SESSION_KEY)
- s.modified = True
- s.save()
-
- i2 = s["item"]
- self.assertFalse(i2._deferred)
-
def test_ticket_16409(self):
# Regression for #16409 - make sure defer() and only() work with annotate()
self.assertIsInstance(
diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py
index 3cc937d58d..41997c98fb 100644
--- a/tests/serializers/tests.py
+++ b/tests/serializers/tests.py
@@ -1,4 +1,3 @@
-import pickle
from datetime import datetime
from functools import partialmethod
from io import StringIO
@@ -6,12 +5,11 @@ from unittest import mock, skipIf
from django.core import serializers
from django.core.serializers import SerializerDoesNotExist
-from django.core.serializers.base import PickleSerializer, ProgressBar
+from django.core.serializers.base import ProgressBar
from django.db import connection, transaction
from django.http import HttpResponse
from django.test import SimpleTestCase, override_settings, skipUnlessDBFeature
-from django.test.utils import Approximate, ignore_warnings
-from django.utils.deprecation import RemovedInDjango50Warning
+from django.test.utils import Approximate
from .models import (
Actor,
@@ -487,31 +485,6 @@ class SerializersTransactionTestBase:
self.assertEqual(art_obj.author.name, "Agnes")
-class PickleSerializerTests(SimpleTestCase):
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_serializer_protocol(self):
- serializer = PickleSerializer(protocol=3)
- self.assertEqual(serializer.protocol, 3)
- # If protocol is not provided, it defaults to pickle.HIGHEST_PROTOCOL
- serializer = PickleSerializer()
- self.assertEqual(serializer.protocol, pickle.HIGHEST_PROTOCOL)
-
- @ignore_warnings(category=RemovedInDjango50Warning)
- def test_serializer_loads_dumps(self):
- serializer = PickleSerializer()
- test_data = "test data"
- dump = serializer.dumps(test_data)
- self.assertEqual(serializer.loads(dump), test_data)
-
- def test_serializer_warning(self):
- msg = (
- "PickleSerializer is deprecated due to its security risk. Use "
- "JSONSerializer instead."
- )
- with self.assertRaisesMessage(RemovedInDjango50Warning, msg):
- PickleSerializer()
-
-
def register_tests(test_class, method_name, test_func, exclude=()):
"""
Dynamically create serializer tests to ensure that all registered