mirror of
https://github.com/django/django.git
synced 2025-01-03 06:55:47 +00:00
Refs #29708 -- Removed PickleSerializer per deprecation timeline.
This commit is contained in:
parent
23c8787439
commit
b119f4329c
@ -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
|
||||
|
@ -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."""
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user