T07 · Tool Hijacking and Spoofing
- Location
scripts/run.py:193- Finding
Unverified Python Module Execution from Outside the Audited Skill Directory
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run.py, lines 193–200
Vulnerability Type: Untrusted external module loading
Risk Level: Mediumpython _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 directory and executes_shared/doc-preprocess/scripts/preprocess.pythroughexec_module().Python modules can run arbitrary top-level code during import. The implementation verifies only that the shared directory exists; it does not verify the module's ownership, permissions, canonical trusted location, version, or cryptographic integrity. Consequently, the effective executable code is not limited to the reviewed package.
Exploitation requires an attacker to create or modify the module at the computed shared path. If that condition is met, a preprocessing error provides the trigger needed to load it.
Attack Path
- The attacker obtains write access to the computed
_shared/doc-preprocess/scriptsdirectory or itspreprocess.pyfile. - The attacker places malicious top-level Python code in
preprocess.py. - The attacker or a victim invokes the skill with an input that causes the local preprocessor to raise
PreprocessError, such as an input requiring unavailable preprocessing support. - The exception handler locates the external shared directory.
exec_module()executes the malicious module during import.- The payload runs with the same operating-system identity, filesystem access, ...[truncated 633 chars]
- The attacker obtains write access to the computed
- Remediation
View remediation
Remediation Suggestions
- Remove the dynamic fallback and keep all executable preprocessing logic inside the reviewed skill package.
- If shared preprocessing is required, distribute it as a version-pinned, integrity-verified dependency installed from a trusted source.
- Resolve the module path with
Path.resolve()and verify that it is under an explicitly configured trusted root. - Verify the module against an allowlisted cryptographic hash or signed manifest before loading it.
- Reject shared modules or parent directories writable by untrusted users.
- Avoid executing arbitrary Python source as a recovery mechanism. Prefer a narrow, versioned interface to a separately managed component.
- Run document preprocessing in a sandbox with minimal filesystem, network, and environment access.
