Skip to content

Commit 3c53444

Browse files
authored
Prevent trusting modules with matching prefix (ipython#15022)
### Fixes ipython#15021 Modified module trust validation to require exact name match or proper submodule notation (with dot separator), preventing modules like `my_fake` from being trusted when only `my` is in the allowlist.
2 parents b717328 + 32358c5 commit 3c53444

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

IPython/core/guarded_eval.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ def _has_original_dunder_external(
165165
value_module = getmodule(value_type)
166166
if not value_module or not value_module.__name__:
167167
return False
168-
if value_module.__name__.startswith(member_type.__name__):
168+
if (
169+
value_module.__name__ == member_type.__name__
170+
or value_module.__name__.startswith(member_type.__name__ + ".")
171+
):
169172
return True
170173
if method_name == "__getattribute__":
171174
# we have to short-circuit here due to an unresolved issue in

tests/test_completer.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,9 +1481,14 @@ def __getattr__(self, attr):
14811481
sys.modules["my.unsafe.lib"] = unsafe_lib
14821482
exec(factory_code, unsafe_lib.__dict__)
14831483

1484+
fake_safe_lib = types.ModuleType("my_fake_lib")
1485+
sys.modules["my_fake_lib"] = fake_safe_lib
1486+
exec(factory_code, fake_safe_lib.__dict__)
1487+
14841488
ip = get_ipython()
14851489
ip.user_ns["safe_list_factory"] = safe_lib.ListFactory()
14861490
ip.user_ns["unsafe_list_factory"] = unsafe_lib.ListFactory()
1491+
ip.user_ns["fake_safe_factory"] = fake_safe_lib.ListFactory()
14871492
complete = ip.Completer.complete
14881493
with (
14891494
evaluation_policy("limited", allowed_getattr_external={"my.safe.lib"}),
@@ -1506,6 +1511,8 @@ def __getattr__(self, attr):
15061511
self.assertIn(".append", matches)
15071512
_, matches = complete(line_buffer="unsafe_list_factory.example.")
15081513
self.assertIn(".append", matches)
1514+
_, matches = complete(line_buffer="fake_safe_factory.example.")
1515+
self.assertNotIn(".append", matches)
15091516

15101517
with (
15111518
evaluation_policy("limited"),

0 commit comments

Comments
 (0)