Control: tags 1131472 + patch Control: tags 1131472 + pending Dear maintainer,
I've prepared an NMU for deepdiff (versioned as 8.6.2-0.1) and uploaded it to DELAYED/2. Please feel free to tell me if I should cancel it. cu Adrian
diffstat for deepdiff-8.6.1 deepdiff-8.6.2 .bumpversion.cfg | 2 - AUTHORS.md | 1 CHANGELOG.md | 3 ++ CITATION.cff | 2 - README.md | 7 ++++- debian/changelog | 9 +++++++ deepdiff/__init__.py | 2 - deepdiff/serialization.py | 35 ++++++++++++++++++++++++++++- docs/authors.rst | 1 docs/changelog.rst | 3 ++ docs/conf.py | 4 +-- docs/index.rst | 7 +++++ pyproject.toml | 2 - tests/test_serialization.py | 52 ++++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 120 insertions(+), 10 deletions(-) diff -Nru deepdiff-8.6.1/AUTHORS.md deepdiff-8.6.2/AUTHORS.md --- deepdiff-8.6.1/AUTHORS.md 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/AUTHORS.md 2026-03-18 19:26:35.000000000 +0200 @@ -76,3 +76,4 @@ - [Jim Cipar](https://github.com/jcipar) for the fix recursion depth limit when hashing numpy.datetime64 - [Enji Cooper](https://github.com/ngie-eign) for converting legacy setuptools use to pyproject.toml - [Diogo Correia](https://github.com/diogotcorreia) for reporting security vulnerability in Delta and DeepDiff that could allow remote code execution. +- [am-periphery](https://github.com/am-periphery) for reporting CVE-2026-33155: denial-of-service via crafted pickle payloads triggering massive memory allocation. diff -Nru deepdiff-8.6.1/.bumpversion.cfg deepdiff-8.6.2/.bumpversion.cfg --- deepdiff-8.6.1/.bumpversion.cfg 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/.bumpversion.cfg 2026-03-18 19:26:35.000000000 +0200 @@ -1,5 +1,5 @@ [bumpversion] -current_version = 8.6.1 +current_version = 8.6.2 commit = True tag = True tag_name = {new_version} diff -Nru deepdiff-8.6.1/CHANGELOG.md deepdiff-8.6.2/CHANGELOG.md --- deepdiff-8.6.1/CHANGELOG.md 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/CHANGELOG.md 2026-03-18 19:26:35.000000000 +0200 @@ -1,5 +1,8 @@ # DeepDiff Change log +- v8-6-2 + - Security fix (CVE-2026-33155): Prevent denial-of-service via crafted pickle payloads that trigger massive memory allocation through the REDUCE opcode. Size-sensitive callables like `bytes()` and `bytearray()` are now wrapped to reject allocations exceeding 128 MB. + - v8-6-1 - Patched security vulnerability in the Delta class which was vulnerable to class pollution via its constructor, and when combined with a gadget available in DeltaDiff itself, it could lead to Denial of Service and Remote Code Execution (via insecure Pickle deserialization). diff -Nru deepdiff-8.6.1/CITATION.cff deepdiff-8.6.2/CITATION.cff --- deepdiff-8.6.1/CITATION.cff 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/CITATION.cff 2026-03-18 19:26:35.000000000 +0200 @@ -5,6 +5,6 @@ given-names: "Sep" orcid: "https://orcid.org/0009-0009-5828-4345" title: "DeepDiff" -version: 8.6.1 +version: 8.6.2 date-released: 2024 url: "https://github.com/seperman/deepdiff" diff -Nru deepdiff-8.6.1/debian/changelog deepdiff-8.6.2/debian/changelog --- deepdiff-8.6.1/debian/changelog 2025-12-22 19:20:48.000000000 +0200 +++ deepdiff-8.6.2/debian/changelog 2026-05-06 21:17:37.000000000 +0300 @@ -1,3 +1,12 @@ +deepdiff (8.6.2-0.1) unstable; urgency=medium + + * Non-maintainer upload. + * New upstream release. + - CVE-2026-33155: Memory Exhaustion DoS through SAFE_TO_IMPORT + (Closes: #1131472) + + -- Adrian Bunk <[email protected]> Wed, 06 May 2026 21:17:37 +0300 + deepdiff (8.6.1-1) unstable; urgency=medium * Team upload. diff -Nru deepdiff-8.6.1/deepdiff/__init__.py deepdiff-8.6.2/deepdiff/__init__.py --- deepdiff-8.6.1/deepdiff/__init__.py 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/deepdiff/__init__.py 2026-03-18 19:26:35.000000000 +0200 @@ -1,6 +1,6 @@ """This module offers the DeepDiff, DeepSearch, grep, Delta and DeepHash classes.""" # flake8: noqa -__version__ = '8.6.1' +__version__ = '8.6.2' import logging if __name__ == '__main__': diff -Nru deepdiff-8.6.1/deepdiff/serialization.py deepdiff-8.6.2/deepdiff/serialization.py --- deepdiff-8.6.1/deepdiff/serialization.py 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/deepdiff/serialization.py 2026-03-18 19:26:35.000000000 +0200 @@ -331,6 +331,35 @@ return "\n".join(f"{prefix}{r}" for r in result) +# Maximum size allowed for integer arguments to constructors that allocate +# memory proportional to the argument (e.g. bytes(n), bytearray(n)). +# This prevents denial-of-service via crafted pickle payloads. (CVE-2026-33155) +_MAX_ALLOC_SIZE = 128 * 1024 * 1024 # 128 MB + +# Callables where an integer argument directly controls memory allocation size. +_SIZE_SENSITIVE_CALLABLES = frozenset({bytes, bytearray}) + + +class _SafeConstructor: + """Wraps a type constructor to prevent excessive memory allocation via the REDUCE opcode.""" + __slots__ = ('_wrapped',) + + def __init__(self, wrapped): + self._wrapped = wrapped + + def __call__(self, *args, **kwargs): + for arg in args: + if isinstance(arg, int) and arg > _MAX_ALLOC_SIZE: + raise pickle.UnpicklingError( + "Refusing to create {}() with size {}: " + "exceeds the maximum allowed size of {} bytes. " + "This could be a denial-of-service attack payload.".format( + self._wrapped.__name__, arg, _MAX_ALLOC_SIZE + ) + ) + return self._wrapped(*args, **kwargs) + + class _RestrictedUnpickler(pickle.Unpickler): def __init__(self, *args, **kwargs): @@ -355,7 +384,11 @@ module_obj = sys.modules[module] except KeyError: raise ModuleNotFoundError(MODULE_NOT_FOUND_MSG.format(module_dot_class)) from None - return getattr(module_obj, name) + cls = getattr(module_obj, name) + # Wrap size-sensitive callables to prevent DoS via large allocations + if cls in _SIZE_SENSITIVE_CALLABLES: + return _SafeConstructor(cls) + return cls # Forbid everything else. raise ForbiddenModule(FORBIDDEN_MODULE_MSG.format(module_dot_class)) from None diff -Nru deepdiff-8.6.1/docs/authors.rst deepdiff-8.6.2/docs/authors.rst --- deepdiff-8.6.1/docs/authors.rst 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/docs/authors.rst 2026-03-18 19:26:35.000000000 +0200 @@ -118,6 +118,7 @@ - `Enji Cooper <https://github.com/ngie-eign>`__ for converting legacy setuptools use to pyproject.toml - `Diogo Correia <https://github.com/diogotcorreia>`__ for reporting security vulnerability in Delta and DeepDiff that could allow remote code execution. +- `am-periphery <https://github.com/am-periphery>`__ for reporting CVE-2026-33155: denial-of-service via crafted pickle payloads triggering massive memory allocation. .. _Sep Dehpour (Seperman): http://www.zepworks.com diff -Nru deepdiff-8.6.1/docs/changelog.rst deepdiff-8.6.2/docs/changelog.rst --- deepdiff-8.6.1/docs/changelog.rst 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/docs/changelog.rst 2026-03-18 19:26:35.000000000 +0200 @@ -5,6 +5,9 @@ DeepDiff Changelog +- v8-6-2 + - Security fix (CVE-2026-33155): Prevent denial-of-service via crafted pickle payloads that trigger massive memory allocation through the REDUCE opcode. Size-sensitive callables like ``bytes()`` and ``bytearray()`` are now wrapped to reject allocations exceeding 128 MB. + - v8-6-1 - Patched security vulnerability in the Delta class which was vulnerable to class pollution via its constructor, and when combined with a gadget available in DeltaDiff itself, it could lead to Denial of Service and Remote Code Execution (via insecure Pickle deserialization). diff -Nru deepdiff-8.6.1/docs/conf.py deepdiff-8.6.2/docs/conf.py --- deepdiff-8.6.1/docs/conf.py 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/docs/conf.py 2026-03-18 19:26:35.000000000 +0200 @@ -64,9 +64,9 @@ # built documents. # # The short X.Y version. -version = '8.6.1' +version = '8.6.2' # The full version, including alpha/beta/rc tags. -release = '8.6.1' +release = '8.6.2' load_dotenv(override=True) DOC_VERSION = os.environ.get('DOC_VERSION', version) diff -Nru deepdiff-8.6.1/docs/index.rst deepdiff-8.6.2/docs/index.rst --- deepdiff-8.6.1/docs/index.rst 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/docs/index.rst 2026-03-18 19:26:35.000000000 +0200 @@ -4,7 +4,7 @@ contain the root `toctree` directive. -DeepDiff 8.6.1 documentation! +DeepDiff 8.6.2 documentation! ============================= ******* @@ -31,6 +31,11 @@ What Is New *********** +DeepDiff 8-6-2 +-------------- + + - Security fix (CVE-2026-33155): Prevent denial-of-service via crafted pickle payloads that trigger massive memory allocation through the REDUCE opcode. Size-sensitive callables like ``bytes()`` and ``bytearray()`` are now wrapped to reject allocations exceeding 128 MB. + DeepDiff 8-6-1 -------------- diff -Nru deepdiff-8.6.1/pyproject.toml deepdiff-8.6.2/pyproject.toml --- deepdiff-8.6.1/pyproject.toml 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/pyproject.toml 2026-03-18 19:26:35.000000000 +0200 @@ -4,7 +4,7 @@ [project] name = "deepdiff" -version = "8.6.1" +version = "8.6.2" dependencies = [ "orderly-set>=5.4.1,<6", ] diff -Nru deepdiff-8.6.1/README.md deepdiff-8.6.2/README.md --- deepdiff-8.6.1/README.md 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/README.md 2026-03-18 19:26:35.000000000 +0200 @@ -1,4 +1,4 @@ -# DeepDiff v 8.6.1 +# DeepDiff v 8.6.2   @@ -17,12 +17,15 @@ Tested on Python 3.9+ and PyPy3. -- **[Documentation](https://zepworks.com/deepdiff/8.6.1/)** +- **[Documentation](https://zepworks.com/deepdiff/8.6.2/)** ## What is new? Please check the [ChangeLog](CHANGELOG.md) file for the detailed information. +DeepDiff 8-6-2 +- **Security (CVE-2026-33155):** Fixed a memory exhaustion DoS vulnerability in `_RestrictedUnpickler` by limiting the maximum allocation size for `bytes` and `bytearray` during deserialization. + DeepDiff 8-6-1 - Patched security vulnerability in the Delta class which was vulnerable to class pollution via its constructor, and when combined with a gadget available in DeltaDiff itself, it could lead to Denial of Service and Remote Code Execution (via insecure Pickle deserialization). diff -Nru deepdiff-8.6.1/tests/test_serialization.py deepdiff-8.6.2/tests/test_serialization.py --- deepdiff-8.6.1/tests/test_serialization.py 2025-09-03 22:38:30.000000000 +0300 +++ deepdiff-8.6.2/tests/test_serialization.py 2026-03-18 19:26:35.000000000 +0200 @@ -155,6 +155,58 @@ load_path_content(path) +class TestPicklingSecurity: + + @pytest.mark.skipif(sys.platform == "win32", reason="Resource module is Unix-only") + def test_restricted_unpickler_memory_exhaustion_cve(self): + """CVE-2026-33155: Prevent DoS via massive allocation through REDUCE opcode. + + The payload calls bytes(10_000_000_000) which is allowed by find_class + but would allocate ~9.3GB of memory. The fix should reject this before + the allocation happens. + """ + import resource + + # 1. Cap memory to 500MB to prevent system freezes during the test + soft, hard = resource.getrlimit(resource.RLIMIT_AS) + maxsize_bytes = 500 * 1024 * 1024 + resource.setrlimit(resource.RLIMIT_AS, (maxsize_bytes, hard)) + + try: + # 2. Malicious payload: attempts to allocate ~9.3GB via bytes(10000000000) + # This uses allowed builtins but passes a massive integer via REDUCE + payload = ( + b"(dp0\n" + b"S'_'\n" + b"cbuiltins\nbytes\n" + b"(I10000000000\n" + b"tR" + b"s." + ) + + # 3. After the patch, deepdiff should catch the size violation + # and raise UnpicklingError before attempting allocation. + with pytest.raises((ValueError, UnpicklingError)): + pickle_load(payload) + finally: + # Restore original memory limit so other tests are not affected + resource.setrlimit(resource.RLIMIT_AS, (soft, hard)) + + def test_restricted_unpickler_allows_small_bytes(self): + """Ensure legitimate small bytes objects can still be deserialized.""" + # Payload: {'_': bytes(100)} — well within the 128MB limit + payload = ( + b"(dp0\n" + b"S'_'\n" + b"cbuiltins\nbytes\n" + b"(I100\n" + b"tR" + b"s." + ) + result = pickle_load(payload) + assert result == {'_': bytes(100)} + + class TestPickling: def test_serialize(self):

