T08 · Insecure Dependencies
Error
- Location
- scripts/pareto.py:8
- Finding
- Unsafe External Module Resolution Enables Dependency Hijacking<![CDATA[ ## Vulnerability Details **File Location**: `scripts/pareto.py`, lines 8–12 **Vulnerability Type**: Unsafe Python import path manipulation **Risk Level**: High ### Vulnerable Code ```python _REPO_ROOT = Path(__file__).resolve().parents[3] if str(_REPO_ROOT) not in sys.path: sys.path.insert(0, str(_REPO_ROOT)) from lib.common import read_json, write_json, utc_now_iso ``` ### Technical Analysis The script calculates a high-level ancestor directory, places it at the beginning of `sys.path`, and imports `lib.common` from that location. In the audited layout, `parents[3]` resolves outside the Skill artifact, potentially as broadly as `/tmp`. The audited artifact does not include `lib.common`. Consequently, the effective implementation of `read_json`, `write_json`, and `utc_now_iso` depends on files available in the surrounding runtime environment. Python executes top-level module code when importing a module. If an attacker can create a `lib/common.py` file in the prepended directory, importing `scripts/pareto.py` can execute attacker-controlled Python code before any Pareto operation occurs. Placing a broad, potentially shared or writable directory first in `sys.path` creates a dependency-hijacking boundary. The tests reinforce this external dependency by similarly modifying `sys.path` and importing from `lib`, rather than verifying a dependency bundled with the artifact. ### Attack Path 1. The attacker obtains write access to the ancestor directory inserted into `sys.path`. 2. The attacker creates a package structure such as: ```text lib/ __init__.py common.py ``` 3. The attacker places executable Python statements in `lib/common.py`. 4. A user, evaluator, or Agent imports or invokes `scripts/pareto.py`. 5. Python resolves `lib.common` from the attacker-controlled location. 6. Top-level code in the malicious module executes with the privileges of the invoking process. ### Impact Assessment Successful exploitation provi ...[truncated 601 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Bundle `common` inside the audited package and use an explicit package-relative import: ```python from .common import read_json, write_json, utc_now_iso ``` 2. Remove all broad ancestor-directory insertion into `sys.path`. 3. Convert the project into a normal Python package with a defined package root. 4. If `lib.common` must be an external dependency: - Declare it in a locked dependency manifest. - Pin the exact version and verify package hashes. - Install it into an isolated virtual environment. - Do not resolve it from shared temporary or working directories. 5. Add a test that verifies the resolved module path is within an approved package or virtual-environment directory: ```python import lib.common assert Path(lib.common.__file__).resolve().is_relative_to(APPROVED_PACKAGE_ROOT) ``` 6. Run the Skill with a restricted filesystem and environment so that untrusted users cannot place modules in any import-search directory. ]]>
