ADR-013 Phase 2: import guard hardening (round-3 review fixes)

This commit is contained in:
2026-07-18 22:12:27 -04:00
parent 83a5ce79d9
commit bbd5224bcd
2 changed files with 119 additions and 31 deletions

View File

@@ -142,6 +142,52 @@ def test_tampered_submodule_import_raises(guarded):
importlib.import_module(f'plugins.{name}.models')
def test_planted_extension_module_refused(guarded):
"""Finding (round 3): a planted .so standing in for a would-be submodule must
be refused, not handed to the stdlib ExtensionFileLoader unverified."""
import importlib.machinery
guard, plugins_dir, priv, name = guarded
pdir = _write_pkg_plugin(plugins_dir, name)
_stamp(pdir, priv, name)
ext = importlib.machinery.EXTENSION_SUFFIXES[0]
(pdir / 'models' / f'evil{ext}').write_bytes(b'\x7fELF-not-really')
with pytest.raises(PluginVerificationError):
guard.find_spec(f'plugins.{name}.models.evil')
def test_planted_sourceless_pyc_refused(guarded):
"""A sourceless .pyc for a name with no .py must be refused."""
guard, plugins_dir, priv, name = guarded
pdir = _write_pkg_plugin(plugins_dir, name)
_stamp(pdir, priv, name)
(pdir / 'models' / 'evil.pyc').write_bytes(b'\x00garbage')
with pytest.raises(PluginVerificationError):
guard.find_spec(f'plugins.{name}.models.evil')
def test_absent_module_defers(guarded):
"""A genuinely-absent module returns None (normal ModuleNotFoundError)."""
guard, plugins_dir, priv, name = guarded
pdir = _write_pkg_plugin(plugins_dir, name)
_stamp(pdir, priv, name)
assert guard.find_spec(f'plugins.{name}.models.notthere') is None
def test_top_level_plugins_body_neutralized(guarded):
"""Finding (round 3): the top-level plugins/__init__.py runs first and is in
no provenance; the guard must exec an EMPTY body so an attacker-overwritten
plugins/__init__.py cannot execute."""
guard, plugins_dir, priv, name = guarded
(plugins_dir / '__init__.py').write_text('raise RuntimeError("attacker code")')
spec = guard.find_spec('plugins')
assert spec is not None
# the loader carries empty source, not the on-disk body
assert spec.loader._source == b''
assert str(plugins_dir) in spec.submodule_search_locations
def test_install_uninstall_idempotent(tmp_path, keypair):
_, pub_path = keypair
plugins_dir = tmp_path / 'plugins'