T07 · Tool Hijacking and Spoofing
Error
- Location
- scripts/run.py:185
- Finding
- Execution of an Unverified Python Module from an External Writable Path## Vulnerability Details **File Location**: `scripts/run.py:185-192` **Vulnerability Type**: Untrusted local module loading and execution **Risk Level**: High ### Vulnerable Code ```python _shared_dir = Path(__file__).resolve().parent.parents[3] / "_shared" / "doc-preprocess" / "scripts" if not _shared_dir.exists(): print(f"ERROR: 无法读取输入文件,本地预处理失败且 _shared/doc-preprocess 不可用。原因:{exc}", file=sys.stderr) return 1 import importlib.util as _iu _spec = _iu.spec_from_file_location("_shared_preprocess", _shared_dir / "preprocess.py") _sp = _iu.module_from_spec(_spec) _spec.loader.exec_module(_sp) ``` ### Technical Analysis When local preprocessing raises `PreprocessError`, the application constructs a path outside the audited skill package and dynamically executes the `preprocess.py` file found there. For the audited deployment path, `Path(__file__).resolve().parent.parents[3]` resolves to `/tmp`, resulting in the expected module location: ```text /tmp/_shared/doc-preprocess/scripts/preprocess.py ``` The application does not verify the module's cryptographic digest, ownership, permissions, provenance, or containment beneath a trusted application directory. Calling `exec_module()` executes all module-level Python statements immediately. Consequently, any party able to create or replace the expected fallback file can cause arbitrary Python code to run. Exploitation requires local write access to the relevant external directory and an input that causes the primary preprocessor to raise `PreprocessError`. ### Attack Path 1. An attacker with local write access creates or replaces `/tmp/_shared/doc-preprocess/scripts/preprocess.py`. 2. The attacker places arbitrary module-level Python code in that file. 3. The attacker or a victim invokes the skill with an input that causes the bundled preprocessing implementation to raise `PreprocessError`, such as an unsupported or unprocessable document. 4. The exception ...[truncated 838 chars]
- Remediation
- ## Remediation Suggestions - Remove the external dynamic-import fallback and use only the preprocessor shipped inside the reviewed package. - If shared preprocessing is required, package it as a pinned and audited dependency installed in a protected application environment. - Resolve the dependency beneath an immutable, administrator-controlled application root rather than a temporary or broadly writable directory. - Before loading any fallback module, verify its canonical path, owner, permissions, and cryptographic digest against trusted metadata. - Reject symbolic links and ensure every parent directory is not writable by untrusted users. - Avoid `exec_module()` for runtime discovery of source files. Import a statically declared package through a controlled Python environment instead. - Run the skill under a dedicated least-privileged operating-system account and restrict its filesystem and network access to reduce impact if module loading is compromised.
