T09 · Insecure Skill Coding Practices
- Location
scripts/run_research.py:243- Finding
Unvalidated Resume State Enables Execution of Unapproved Local Python Scripts
- Content
View full analysis
list[str]: action_type = action.get("type", "discover") if action_type == "discover": return [sys.executable, str(SEARCH_SCRIPT), "--q", action["query"], "--json", "1"] if action_type == "fetch": return [sys.executable, str(UNLOCKER_SCRIPT), "--url", action["url"], "--clean-content", "true"] folder = action["capability"] scripts = sorted((REPO_ROOT / "skills" / folder / "scripts").glob("*.py")) scripts = [path for path in scripts if "preview" not in path.name] if not scripts: raise FileNotFoundError(f"No executable script for {folder}") script = scripts[0] if action.get("tool_sign"): parameter = TOOL_URL_PARAMETERS.get(action["tool_sign"], "url") return [sys.executable, str(script), "--tool-sign", action["tool_sign"], "--params-json", json.dumps({parameter: action["url"]})] argument = "--job-url" if folder == "scraper-indeed-job-listings" else "--url" return [sys.executable, str(script), argument, action["url"]] ``` The attacker-controlled state is loaded without schema validation or a capability allowlist: ```python def load_or_plan(args: argparse.Namespace) -> tuple[Path, dict[str, Any]]: if args.resume: state_path = args.resume if args.resume.name == "state.json" else args.resume / "state.json" state = json.loads(state_path.read_text(encoding="utf-8")) ``` The selected script is subsequently executed: ```python command = command_for(action) return subprocess.run( command, capture_output=True, text=True, encoding="utf-8", errors="replace", check=False ) ``` ### Technical Analysis The `--resume` feature treats the contents of `state.json` as ...[truncated 2441 chars]- Remediation
View remediation
