T09 · Insecure Skill Coding Practices
- Location
releaser.py:690- Finding
Untrusted Skill Code Is Executed During Validation and Inventory Scans
- Content
View full analysis
Vulnerability Details
File Location:
releaser.py:690-691,releaser.py:839-850,releaser.py:961-962, andreleaser.py:1821
Vulnerability Type: Arbitrary code execution during inspection of untrusted Skills
Risk Level: HighComplete Code Snippets
The validation flow executes the target Skill's selected entry point:
python r = subprocess.run([sys.executable, main, "doctor", "--path", "."], cwd=skill_dir, capture_output=True, text=True, env=env)The functional checks import the target module and launch its entry point:
python mod = os.path.splitext(os.path.basename(entry))[0] # 2) import entry module r = _run([sys.executable, "-c", "import %s" % mod], cwd=skill_dir, timeout=25) if r.returncode == 0: _add("PASS", "Entry module can be imported", "", W["fn_import"]) else: _add("FAIL", "Entry module import failed", (r.stderr or r.stdout).strip()[-200:], W["fn_import"]) # 3) --help smoke test r = _run([sys.executable, entry, "--help"], cwd=skill_dir, timeout=25) if r.returncode == 0: _add("PASS", "Entry --help smoke test passed", "", W["fn_smoke"]) else: _add("WARN", "Entry --help smoke test failed", (r.stderr or r.stdout).strip()[-160:], W["fn_smoke"])The bulk inventory operation also invokes each discovered Skill's entry point:
python if main: env = dict(os.environ) env["RELEASER_VALIDATE_DEPTH"] = "1" r = subprocess.run([sys.executable, main, "doctor", "--path", "."], cwd=d, capture_output=True, text=True, env=env) doc_ok = "Y" if r.returncode == 0 else "N"The lifecycle recheck operation reaches the same validation execution path:
python fails = validate_skill(path, mode="skill", silent=True)Technical Analysis
The project presents
validate,gate,inventory, andrecheckas inspection and governance features, but these operations do not remain static. They execute Python source controlled by the aut ...[truncated 3263 chars]- Remediation
View remediation
Remediation Suggestions
- Make all normal validation, inventory, and lifecycle checks static-only. Parse source with
astand inspect metadata without importing modules or launching target entry points. - Remove automatic execution from bulk
inventoryandrecheckoperations. These commands should never execute every discovered Skill merely to determine readiness. - Place dynamic smoke tests behind an explicit option such as
--execute-untrusted, accompanied by a clear warning that target code will run. - Run any authorized dynamic checks in a disposable sandbox or container with:
- a dedicated unprivileged user;
- no inherited environment variables or credentials;
- networking disabled by default;
- the target mounted read-only;
- a fresh temporary working directory;
- no access to SSH agents, cloud metadata, home directories, or host sockets; and
- strict process, CPU, memory, filesystem, and execution-time limits.
- Perform static secret and policy checks before any optional dynamic execution. This ordering reduces exposure but does not replace isolation.
- Add enforced timeouts to every subprocess, including both
doctorcalls. On timeout, terminate the complete process group rather than only the immediate child. - Document the distinction between static validation and explicitly authorized dynamic testing so users can make an informed trust decision.
- Make all normal validation, inventory, and lifecycle checks static-only. Parse source with
