T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/validate_skill.py:682
- Finding
- Validation of an Untrusted Skill Executes Its Project-Supplied Fingerprint Script<![CDATA[ ## Vulnerability Details **File Location**: `scripts/validate_skill.py`, lines 682–768 **Vulnerability Type**: Arbitrary code execution through an untrusted validation target **Risk Level**: High ### Vulnerable Code The validator derives the executable path directly from the user-controlled `--skill-dir` directory: ```python import subprocess fp = skill_dir / "scripts" / "fingerprint.py" ``` It subsequently starts that project-supplied Python file as a subprocess: ```python r = subprocess.run( [sys.executable, str(fp), "parse", raw, "--skill-dir", str(skill_dir)], capture_output=True, text=True, encoding="utf-8") ``` ### Technical Analysis The validator accepts an arbitrary Skill directory through its documented `--skill-dir` command-line option. It then treats `scripts/fingerprint.py` inside that directory as an executable validation component. Although the validator statically parses selected assignments from the file before execution, this does not establish that the file is safe. An attacker can preserve the expected `CORE_ATOM_KEYS` and `DEPENDENCY_RULES` assignments while adding arbitrary top-level Python statements. Those statements execute immediately when the subprocess starts, before argument parsing or fingerprint validation occurs. The vulnerability crosses a trust boundary: a trusted auditing utility executes code supplied by the untrusted artifact it is intended to inspect. Passing arguments as a list prevents shell metacharacter injection, but it does not mitigate execution of a malicious Python program. ### Attack Path 1. An attacker prepares a Skill directory containing the expected structure and documentation. 2. The attacker supplies a crafted `scripts/fingerprint.py`. 3. The crafted file retains the constants expected by the validator so that static checks do not immediately reject it. 4. The attacker adds malicious top-level Python code to the file. 5. The Skill documentation contains at least one matching ...[truncated 1189 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Do not execute files from the target Skill.** Move fingerprint parsing into the trusted validator and process fingerprint strings as data. 2. **Use a trusted parser implementation.** If code reuse is required, import or invoke a parser from the validator’s own installation directory, not from `--skill-dir`. 3. **Separate trusted tooling from inspected content.** Resolve trusted utility paths relative to the running validator: ```python trusted_fp = Path(__file__).resolve().parent / "fingerprint.py" ``` This is appropriate only if that file belongs to the trusted validator package rather than the inspected artifact. 4. **Prefer direct library calls over subprocesses.** Refactor fingerprint parsing into a side-effect-free trusted module and call its parsing function directly. 5. **Add a regression test.** Create a target Skill whose `fingerprint.py` writes a marker file at module initialization. Validation must reject or inspect the target without creating that marker. 6. **Use defense-in-depth isolation.** If target-controlled code must ever run, execute it in a disposable sandbox with: - No host credentials or secrets. - Network access disabled. - A read-only target directory. - No writable host mounts. - Resource and execution-time limits. - A dedicated unprivileged operating-system identity. ]]>
