T09 · Insecure Skill Coding Practices
- Location
src/hooks.py:39- Finding
Arbitrary Code Execution Through Untrusted Workspace Hooks
- Content
View full analysis
Vulnerability Details
File Location:
src/hooks.py, lines 39-56 and 66-73
Vulnerability Type: Untrusted dynamic Python module loading
Risk Level: HighVulnerable Code
python def _load_hooks(self) -> List[Any]: """Load all hooks from the hooks directory.""" hooks = [] for hook_file in self.hooks_path.glob('*.py'): hook = self._load_hook(hook_file) if hook: hooks.append(hook) return hooks def _load_hook(self, hook_file: Path): """Load a single hook from file.""" try: spec = importlib.util.spec_from_file_location( hook_file.stem, hook_file ) if spec and spec.loader: module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) if hasattr(module, 'apply'): return module return None except Exception as e: print(f"⚠️ Failed to load hook {hook_file}: {e}") return None def _apply_hook(self, hook): """Apply a single hook.""" try: hook.apply() except Exception as e: print(f"⚠️ Hook failed: {e}") # Trigger error hook self.trigger_error(e)Technical Analysis
HookManagerscans every*.pyfile in the configured workspace hook directory and loads each file as an executable Python module. There is no hook allowlist, integrity validation, signature verification, ownership or permission check, or explicit approval step.Calling
spec.loader.exec_module(module)executes all module-level statements immediately. Consequently, the laterhasattr(module, 'apply')check is not a security boundary: malicious code has already executed before that check occurs. A qualifying module'sapply()function can subsequently execute additional attacker-controlled code.The configured workspace can be supplied through the CLI's
--workspaceoption. The issue is exploitable whenever an attacker can create or ...[truncated 1701 chars]- Remediation
View remediation
Remediation Suggestions
- Replace directory-wide discovery with an explicit allowlist of trusted hook identifiers and paths.
- Keep executable hooks in an application-owned directory that is not writable by untrusted users or workspace content.
- Resolve each hook path and verify that it remains beneath the trusted hook root before loading it.
- Verify file ownership and reject group- or world-writable hook files and parent directories where supported.
- Pin and verify approved hook contents using cryptographic hashes or signed manifests.
- Require explicit administrator or user approval before enabling a newly discovered or modified hook.
- Do not treat the presence of an
apply()function as validation because module import has already executed top-level code. - Prefer a declarative, schema-validated hook format over executable Python when hooks only need to describe learning behavior.
- If third-party executable hooks are necessary, execute them in a restricted subprocess or sandbox with minimal filesystem, environment, and network access.
- Add tests confirming that unapproved hooks, path escapes, symlink escapes, and files with unsafe ownership or permissions are rejected.
