T09 · Insecure Skill Coding Practices
- Location
scripts/gumroad_batch_publish.py:130- Finding
Untrusted Manifest Paths Permit Arbitrary Local File Upload
- Content
View full analysis
dict[str, Any]: return json.loads(path.read_text(encoding="utf-8")) ``` ```python def create_product(record: dict[str, Any], *, publish: bool, dry_run: bool) -> dict[str, Any]: cmd = [ "products", "create", "--name", record["title"], "--price", str(record["price"]), "--description", record.get("description") or "", "--custom-summary", record.get("custom_summary") or "", "--file", record["file"], "--file-name", record.get("file_name") or Path(record["file"]).name, "--yes", ] if record.get("cover_image"): cmd += ["--cover-image", record["cover_image"]] if record.get("thumbnail"): cmd += ["--thumbnail", record["thumbnail"]] ``` ```python def cmd_publish(args: argparse.Namespace) -> None: if not args.yes and not args.dry_run: raise SystemExit("Refusing live batch publish without --yes after explicit user confirmation.") path = Path(args.manifest) manifest = load_manifest(path) records = selected_records(manifest, args.limit, args.only_sku) results = [] for record in records: result = create_product(record, publish=args.publish, dry_run=args.dry_run) results.append({"sku": record.get("sku"), "product_id": record.get("product_id"), "verified": record.get("verified"), "response": result if args.dry_run else None}) save_manifest(path, manifest) ``` ### Technical Analysis The `publish` operation treats an existing JSON manifest as trusted input. The `file`, `cover_image`, and `thumbnail` values are passed directly to the authenticated Gumroad CLI without confirming ...[truncated 1953 chars]- Remediation
View remediation
