CVE-2026-33155
Description
DeepDiff is a project focused on Deep Difference and search of any Python data. From version 5.0.0 to before version 8.6.2, the pickle unpickler _RestrictedUnpickler validates which classes can be loaded but does not limit their constructor arguments. A few of the types in SAFE_TO_IMPORT have constructors that allocate memory proportional to their input (builtins.bytes, builtins.list, builtins.range). A 40-byte pickle payload can force 10+ GB of memory, which crashes applications that load delta objects or call pickle_load with untrusted data. This issue has been patched in version 8.6.2.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
deepdiffPyPI | >= 5.0.0, < 8.6.2 | 8.6.2 |
Affected products
1Patches
10d07ec21d12bMerge commit from fork
13 files changed · +111 −10
AUTHORS.md+1 −0 modified@@ -76,3 +76,4 @@ Authors in order of the timeline of their contributions: - [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.
.bumpversion.cfg+1 −1 modified@@ -1,5 +1,5 @@ [bumpversion] -current_version = 8.6.1 +current_version = 8.6.2 commit = True tag = True tag_name = {new_version}
CHANGELOG.md+3 −0 modified@@ -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).
CITATION.cff+1 −1 modified@@ -5,6 +5,6 @@ authors: 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"
deepdiff/__init__.py+1 −1 modified@@ -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__':
deepdiff/serialization.py+34 −1 modified@@ -331,6 +331,35 @@ def pretty(self, prefix: Optional[Union[str, Callable]]=None): 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 @@ def find_class(self, module, name): 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
docs/authors.rst+1 −0 modified@@ -118,6 +118,7 @@ and polars support. - `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
docs/changelog.rst+3 −0 modified@@ -5,6 +5,9 @@ Changelog 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).
docs/conf.py+2 −2 modified@@ -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)
docs/index.rst+6 −1 modified@@ -4,7 +4,7 @@ contain the root `toctree` directive. -DeepDiff 8.6.1 documentation! +DeepDiff 8.6.2 documentation! ============================= ******* @@ -31,6 +31,11 @@ The DeepDiff library includes the following modules: 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 --------------
pyproject.toml+1 −1 modified@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi" [project] name = "deepdiff" -version = "8.6.1" +version = "8.6.2" dependencies = [ "orderly-set>=5.4.1,<6", ]
README.md+5 −2 modified@@ -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).
tests/test_serialization.py+52 −0 modified@@ -155,6 +155,58 @@ def test_load_path_content_when_unsupported_format(self): 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):
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/qlustered/deepdiff/commit/0d07ec21d12b46ef4e489383b363eadc22d990fbnvdPatchWEB
- github.com/qlustered/deepdiff/security/advisories/GHSA-54jj-px8x-5w5qnvdExploitVendor AdvisoryWEB
- github.com/advisories/GHSA-54jj-px8x-5w5qghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-33155ghsaADVISORY
News mentions
0No linked articles in our index yet.