T09 · Insecure Skill Coding Practices
- Location
scripts/scraper.py:103- Finding
Unrestricted output path allows arbitrary writable-file overwrite
- Content
View full analysis
None: output.write_text(json.dumps([item.to_dict() for item in items], ensure_ascii=False, indent=2), encoding="utf-8") def write_csv(items: list[VideoData], output: Path) -> None: if not items: output.write_text("", encoding="utf-8") return fieldnames = list(items[0].to_dict().keys()) with output.open("w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for item in items: row = item.to_dict() row["tags"] = "|".join(row["tags"]) writer.writerow(row) ``` ```python if args.output: output = Path(args.output) if args.format == "csv": write_csv(items, output) else: write_json(items, output) ``` Equivalent Node.js implementation: ```javascript function saveToJson(videos, filepath) { const data = videos.map(v => ({ title: v.title, description: v.description, author: v.author, play_count: v.play_count, like_count: v.like_count, comment_count: v.comment_count, share_count: v.share_count, url: v.url, tags: v.tags, publish_time: v.publish_time })); fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf-8'); console.log(`💾 已保存到: ${filepath}`); } function saveToCsv(videos, filepath) { if (!videos.length) return; const headers = Object.keys(videos[0]); const csvContent = [ headers.join(','), ...videos.map(v => headers.map(h => { const value = Array.isArray(v[ ...[truncated 2465 chars]- Remediation
View remediation
Path: requested = Path(user_value) if requested.is_absolute() or ".." in requested.parts: raise ValueError("Absolute paths and path traversal are not allowed") destination = (EXPORT_ROOT / requested).resolve() if destination != EXPORT_ROOT and EXPORT_ROOT not in destination.parents: raise ValueError("Output path escapes the export directory") return destination ``` 4. Apply equivalent `path.resolve` and containment validation in the Node.js implementation. 5. Refuse to replace existing files by default, or require explicit user confirmation or a dedicated `--overwrite` option. 6. Restrict permitted extensions to `.json` and `.csv`, and ensure the selected format matches the destination extension. 7. Run the Skill under a low-privilege account with write access limited to its export directory. ]]>
