T07 · Tool Hijacking and Spoofing
- Location
scripts/run.py:185- Finding
Execution of an Unverified Python Module from an External Writable Path
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run.py:185-192
Vulnerability Type: Untrusted local module loading and execution
Risk Level: HighVulnerable 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 thepreprocess.pyfile 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.pyThe 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
- An attacker with local write access creates or replaces
/tmp/_shared/doc-preprocess/scripts/preprocess.py. - The attacker places arbitrary module-level Python code in that file.
- 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. - The exception ...[truncated 838 chars]
- An attacker with local write access creates or replaces
- Remediation
View 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.
