Skip to content

Commit b697d65

Browse files
committed
Changed deepdiff/delta.py:237 so dunder traversal from check_elem() raises immediately instead of
going through _raise_or_log(). Also added full-path preflight validation in _get_elements_and_details() so the set_item_added path introduced in the last commit cannot silently skip malicious dunder paths.
1 parent a349699 commit b697d65

2 files changed

Lines changed: 11 additions & 8 deletions

File tree

deepdiff/delta.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,7 @@ def _get_elem_and_compare_to_old_value(
237237
forced_old_value=None,
238238
next_element=None,
239239
):
240-
try:
241-
check_elem(elem)
242-
except ValueError as error:
243-
self._raise_or_log(UNABLE_TO_GET_ITEM_MSG.format(path_for_err_reporting, error))
244-
return not_found
240+
check_elem(elem)
245241
# if forced_old_value is not None:
246242
try:
247243
if action == GET:
@@ -525,6 +521,8 @@ def _do_pre_process(self):
525521
def _get_elements_and_details(self, path):
526522
try:
527523
elements = _path_to_elements(path)
524+
for elem, _ in elements:
525+
check_elem(elem)
528526
if len(elements) > 1:
529527
elements_subset = elements[:-2]
530528
if len(elements_subset) != len(elements):
@@ -546,8 +544,9 @@ def _get_elements_and_details(self, path):
546544
obj = self
547545
# obj = self.get_nested_obj(obj=self, elements=elements[:-1])
548546
elem, action = elements[-1] # type: ignore
549-
check_elem(elem)
550547
except Exception as e:
548+
if isinstance(e, ValueError) and str(e) == "traversing dunder attributes is not allowed":
549+
raise
551550
self._raise_or_log(UNABLE_TO_GET_ITEM_MSG.format(path, e))
552551
return None
553552
else:

tests/test_security.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ def test_builtins_int(self):
4242
assert 42 == int("41") + 1
4343

4444
# Apply Delta to mydict
45-
result = mydict + Delta(pollute_int)
45+
with pytest.raises(ValueError) as exc_info:
46+
mydict + Delta(pollute_int)
47+
assert "traversing dunder attributes is not allowed" == str(exc_info.value)
4648

4749
assert 1337 == int("1337")
4850

@@ -128,6 +130,8 @@ def myfunc(self):
128130
PWNED = False
129131
delta = Delta(pollute_global)
130132
assert PWNED is False
131-
b = Foo() + delta
133+
with pytest.raises(ValueError) as exc_info:
134+
Foo() + delta
135+
assert "traversing dunder attributes is not allowed" == str(exc_info.value)
132136

133137
assert PWNED is False

0 commit comments

Comments
 (0)