T09 · Insecure Skill Coding Practices
- Location
mp_builder.py:48- Finding
Unvalidated CLI Names Permit Writes Outside the Intended Project Directory
- Content
View full analysis
Vulnerability Details
File Location:
mp_builder.py:48-66,mp_builder.py:99-103, andmp_builder.py:152-159
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: HighVulnerable Code
python project_dir = Path(project_name) project_dir.mkdir(exist_ok=True) (project_dir / "pages").mkdir(exist_ok=True) (project_dir / "utils").mkdir(exist_ok=True) (project_dir / "components").mkdir(exist_ok=True) (project_dir / "cloudfunctions").mkdir(exist_ok=True) # Create app.json template_data = self.TEMPLATES[template] app_json = { "pages": [f"pages/{p}/main" for p in template_data["pages"]], "window": { "navigationBarTitleText": project_name, "navigationBarBackgroundColor": "#ffffff" } } with open(project_dir / "app.json", "w") as f: json.dump(app_json, f, indent=2, ensure_ascii=False)python page_dir = Path("pages") / page_name page_dir.mkdir(exist_ok=True) with open(page_dir / "generated.md", "w") as f: f.write(code)python func_dir = Path("cloudfunctions") / func_name func_dir.mkdir(exist_ok=True) with open(func_dir / "index.js", "w") as f: f.write(templates[func_name]) with open(func_dir / "package.json", "w") as f: json.dump({"name": func_name, "version": "1.0.0", "dependencies": {"wx-server-sdk": "latest"}}, f, indent=2)Technical Analysis
The
project_name,page_name, andfunc_namevalues originate from the command-line--nameargument and are used directly to construct filesystem paths. The application does not reject absolute paths, path separators, or parent-directory components such as...With
pathlib, joining a base path to an absolute user-supplied path discards the base path. Relative paths containing../can similarly resolve outside the expectedpagesorcloudfunctionsdirectory. The application then opens fixed filenames in write mode, whi ...[truncated 1678 chars]- Remediation
View remediation
Remediation Suggestions
- Treat names as identifiers rather than arbitrary paths. Apply an allowlist such as:
python import re NAME_PATTERN = re.compile(r"^[A-Za-z0-9_-]+$") def validate_name(value: str) -> str: if not NAME_PATTERN.fullmatch(value): raise ValueError("Name may contain only letters, numbers, underscores, and hyphens") return value - Define an explicit workspace root, resolve both the root and candidate path, and verify containment:
python def safe_child(root: Path, name: str) -> Path: validate_name(name) root = root.resolve() candidate = (root / name).resolve() if candidate.parent != root: raise ValueError("Destination escapes the workspace") return candidate - Reject absolute paths,
.and..components, directory separators, null characters, and platform-specific alternate separators. - Consider refusing to overwrite existing files by using exclusive creation mode (
"x") or by requiring an explicit--forceoption. - Check for symbolic links in destination components where the workspace may be writable by another user.
- Run generation with minimal filesystem privileges and isolate the workspace from sensitive source, configuration, and deployment directories.
- Treat names as identifiers rather than arbitrary paths. Apply an allowlist such as:
