GitHub Security Advisory: GHSA-mw26-5g2v-hqw3
Package: deepdiff (PIP)
Severity: CRITICAL (CVSS 0.0)
CWE: CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
Vulnerable versions: >= 5.0.0, <= 8.6.0
Patched in: 8.6.1

Summary: DeepDiff Class Pollution in Delta class leading to DoS, Remote Code Execution, and more

Details:
### Summary
[Python class pollution](https://blog.abdulrah33m.com/prototype-pollution-in-python/) is a novel vulnerability categorized under [CWE-915](https://cwe.mitre.org/data/definitions/915.html). The `Delta` class is vulnerable to class pollution via its constructor, and when combined with a gadget available in DeltaDiff itself, it can lead to Denial of Service and Remote Code Execution (via insecure [Pickle](https://docs.python.org/3/library/pickle.html) deserialization).

The gadget available in DeepDiff allows `deepdiff.serialization.SAFE_TO_IMPORT` to be modified to allow dangerous classes such as `posix.system`, and then perform insecure Pickle deserialization via the Delta class. This potentially allows any Python code to be executed, given that the input to `Delta` is user-controlled.

Depending on the application where DeepDiff is used, this can also lead to other vulnerabilities. For example, in a web application, it might be possible to bypass authentication via class pollution.

### Details

The `Delta` class can take different object types as a parameter in its constructor, such as a `DeltaDiff` object, a dictionary, or even just bytes (that are deserialized via Pickle).

When it takes a dictionary, it is usually in the following format:
```py
Delta({"dictionary_item_added": {"root.myattr['foo']": "bar"}})
```

Trying to apply class pollution here does not work, because there is already a filter in place: https://github.com/seperman/deepdiff/blob/b639fece73fe3ce4120261fdcff3cc7b826776e3/deepdiff/path.py#L23

However, this code only runs when parsing the path from a string.
The `_path_to_elements` function helpfully returns the given input if it is already a list/tuple:
https://github.com/seperman/deepdiff/blob/b639fece73fe3ce4120261fdcff3cc7b826776e3/deepdiff/path.py#L52-L53

This means that it is possible to pass the path as the internal representation used by Delta, bypassing the filter:

```py
Delta(
    {
        "dictionary_item_added": {
            (
                ("root", "GETATTR"),
                ("__init__", "GETATTR"),
                ("__globals__", "GETATTR"),
                ("PWNED", "GET"),
            ): 1337
        }
    },
)
```

Going back to the possible inputs of `Delta`, when it takes a `bytes` as input, it uses pickle to deserialize them.
Care was taken by DeepDiff to prevent arbitrary code execution via the `SAFE_TO_IMPORT` allow list.
https://github.com/seperman/deepdiff/blob/b639fece73fe3ce4120261fdcff3cc7b826776e3/deepdiff/serialization.py#L62-L98
However, using the class pollution in the `Delta`, an attacker can add new entries to this `set`.

This then allows a second call to `Delta` to [unpickle an insecure class](https://davidhamann.de/2020/04/05/exploiting-python-pickle/) that runs `os.system`, for example.

#### Using dict

Usually, class pollution [does not work](https://gist.github.com/CalumHutton/45d33e9ea55bf4953b3b31c84703dfca#technical-details) when traversal starts at a `dict`/`list`/