T09 · Insecure Skill Coding Practices
- Location
baoyu_seedream_ppt.py:179- Finding
Path Traversal Enables Local Markdown Disclosure to the Seedream API
- Content
View full analysis
Vulnerability Details
File Location:
baoyu_seedream_ppt.py:179-195, 247-264;interactive.py:207-220, 250-285, 498-510
Vulnerability Type: Path traversal resulting in local file disclosure
Risk Level: HighVulnerable Code
python # baoyu_seedream_ppt.py:179-195 skill_root = os.path.dirname(os.path.abspath(__file__)) baoyu_root = os.path.join(os.path.dirname(skill_root), "baoyu-infographic") layout_path = os.path.join( baoyu_root, "references", "layouts", f"{args.layout}.md" ) style_path = os.path.join( baoyu_root, "references", "styles", f"{args.style}.md" ) base_prompt_path = os.path.join( baoyu_root, "references", "base-prompt.md" ) if not os.path.exists(layout_path): print(f"❌ 布局不存在: {args.layout}") print(f" 请检查 {layout_path}") sys.exit(1) if not os.path.exists(style_path): print(f"❌ 风格不存在: {args.style}") print(f" 请检查 {style_path}") sys.exit(1)python # baoyu_seedream_ppt.py:203-211 with open(layout_path, 'r', encoding='utf-8') as f: layout_def = f.read() with open(style_path, 'r', encoding='utf-8') as f: style_def = f.read() with open(base_prompt_path, 'r', encoding='utf-8') as f: base_prompt = f.read()python # baoyu_seedream_ppt.py:247-264 full_prompt = base_prompt full_prompt = full_prompt.replace("{{LAYOUT}}", args.layout) full_prompt = full_prompt.replace("{{STYLE}}", args.style) full_prompt = full_prompt.replace("{{ASPECT_RATIO}}", args.aspect) full_prompt = full_prompt.replace("{{LANGUAGE}}", "Chinese") full_prompt = full_prompt.replace("{{LAYOUT_GUIDELINES}}", layout_def) full_prompt = full_prompt.replace("{{STYLE_GUIDELINES}}", style_def) full_prompt = full_prompt.replace("{{CONTENT}}", page_content) full_prompt = full_prompt.replace("{{TEXT_LABELS}}", "") prompt_file = os.path.join(output_dir, f"prompts_page_{page_num:02d}.md") with open(prompt_file, 'w', ...[truncated 3346 chars]- Remediation
View remediation
Remediation Suggestions
- Build explicit allowlists from the available layout and style templates and reject every value not present in those allowlists.
- Reject absolute paths, path separators,
.components, and..components before constructing a path. - Resolve the candidate path and verify that its parent is exactly the expected template directory:
python layouts_dir = (baoyu_root / "references" / "layouts").resolve() available_layouts = {path.stem for path in layouts_dir.glob("*.md")} if layout not in available_layouts: raise ValueError("Unsupported layout") layout_path = (layouts_dir / f"{layout}.md").resolve() if layout_path.parent != layouts_dir: raise ValueError("Invalid layout path")- Apply the same validation independently to styles.
- Validate configuration-loaded values exactly as strictly as direct command-line values.
- Add tests covering
../, absolute paths, nested paths, encoded separators, and valid allowlisted names. - Warn users that slide content and selected template text are sent to an external image-generation provider.
