T08 · Insecure Dependencies
Warning
- Location
- scripts/_stack_invoke.py:12
- Finding
- Execution of Unpinned and Unverified External Stack Tools<![CDATA[ ## Vulnerability Details **File Location**: `scripts/_stack_invoke.py`, lines 12–35 **Vulnerability Type**: Unverified external dependency execution **Risk Level**: Medium ### Vulnerable Code ```python def stack_root() -> Path: env = os.environ.get("LYGO_STACK_ROOT", "").strip() if env: return Path(env).resolve() for p in HERE.parents: if (p / "tools" / "agent_lattice_core.py").is_file(): return p if (p / "tools" / "verify_living_mesh.py").is_file(): return p return Path.cwd() def invoke(tool_name: str, argv: list[str] | None = None) -> int: stack = stack_root() tool = stack / "tools" / tool_name if not tool.is_file(): print( f'{{"verdict":"ERROR","reason":"missing_tool","tool":"{tool_name}","stack":"{stack}"}}', file=sys.stderr, ) return 2 return subprocess.call( [sys.executable, str(tool), *(argv if argv is not None else sys.argv[1:])], cwd=str(stack), ) ``` The public entry-point wrappers invoke fixed external filenames. For example, `scripts/join.py`, lines 1–6: ```python #!/usr/bin/env python3 import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) from _stack_invoke import invoke raise SystemExit(invoke("agent_lattice_join.py")) ``` ### Technical Analysis The packaged Skill does not contain the implementations responsible for identity generation, joining, announcement, gossip, directory management, sentinel processing, hub operation, or verification. Instead, each entry point selects a separate stack directory and executes a Python file from its `tools` subdirectory. The stack location can come from the mutable `LYGO_STACK_ROOT` environment variable, a detected ancestor directory, or the current working directory. Before execution, the launcher only verifies that the selected path is a file. It does not verify: - A cryptographic digest or signature - A p ...[truncated 2008 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bundle the reviewed implementations with the Skill so the audited package contains the code it executes. 2. If external stack tools must remain separate, pin an exact trusted release and verify every executable file against an embedded cryptographic digest or a trusted digital signature before invocation. 3. Require `LYGO_STACK_ROOT` to resolve beneath an explicitly approved canonical directory; fail closed instead of falling back to the current working directory. 4. Resolve the final tool path and verify that it remains inside the approved `tools` directory. 5. Reject symbolic links and require safe ownership and permissions for both the stack root and delegated files. 6. Replace the generic tool-name interface with an immutable allowlist mapping each supported operation to one exact filename. 7. Verify the external stack’s version and compatibility metadata before execution. 8. Document the external stack as a security-sensitive runtime dependency rather than implying that all advertised controls are implemented within this package. 9. Add tests proving that modified files, unknown versions, path escapes, symbolic links, and untrusted stack roots are rejected before subprocess creation. ]]>
