T08 · Insecure Dependencies
Error
- Location
- evals/run_evals.py:7
- Finding
- Untrusted External Python Module Loading via Import Path Manipulation## Vulnerability Details **File Location**: `evals/run_evals.py`, lines 7–10 **Vulnerability Type**: Insecure dependency loading and local module substitution **Risk Level**: High **Vulnerable code:** ```python REPO_ROOT = Path(__file__).resolve().parent.parent.parent.parent sys.path.insert(0, str(REPO_ROOT / "shared")) from eval_framework import main ``` ### Technical Analysis The evaluation runner derives a dependency directory by traversing four parent directories from its own location, prepends the resulting `shared` directory to `sys.path`, and then imports `eval_framework` without validating the module's origin or integrity. In the audited deployment layout, this resolves to `/tmp/shared`, which is outside the audited project directory. Because `sys.path.insert(0, ...)` gives that directory precedence over other import locations, a substituted `eval_framework.py` or `eval_framework` package in that directory is imported first. Python executes module-level code immediately during import, before `main()` is called. This creates a dependency-substitution risk at a local, ancestor-derived path. Exploitation requires an attacker or compromised process to have write access to the resolved external directory. The audit did not establish the directory's actual permissions or confirm that a malicious module exists, so the finding represents an exploitable unsafe loading mechanism rather than evidence of an active payload. ### Attack Path 1. An attacker determines that the evaluation runner imports `eval_framework` from the ancestor-derived `shared` directory. 2. The attacker obtains write access to that directory, directly or through another compromised process. 3. The attacker creates or replaces `/tmp/shared/eval_framework.py`, or an equivalent package, with malicious module-level code and a compatible `main` symbol. 4. A user launches `python evals/run_evals.py`. 5. The runner places `/tmp/shared` at the beginning of ...[truncated 902 chars]
- Remediation
- ## Remediation Suggestions 1. Remove the ancestor-derived `sys.path` modification and package `eval_framework` as a normal trusted dependency. 2. Pin the dependency to an approved version and verify its integrity using lock files and cryptographic hashes. 3. If the framework belongs to the same repository, place it inside a trusted package tree and use an explicit package import. 4. If external loading is unavoidable: - Obtain the dependency root from a trusted, validated configuration. - Resolve the path canonically. - Verify that it is inside an approved directory. - Reject writable shared or temporary directories. - Verify the dependency against an expected cryptographic digest before loading it. 5. Run evaluation tooling under a least-privileged account in a sandbox with restricted filesystem and network access. 6. Add a startup assertion that logs and validates `eval_framework.__file__` against the expected trusted location. 7. Add a security regression test ensuring that an unexpected module in an ancestor or temporary directory cannot shadow the approved framework.
