T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/generate_workflow_blueprint.py:104
- Finding
- Dry-Run Mode Still Creates Directories and Overwrites Files## Vulnerability Details **File Location**: `scripts/generate_workflow_blueprint.py`, lines 17, 31-54, and 104 **Vulnerability Type**: Violation of dry-run semantics and unrestricted file overwrite **Risk Level**: Medium **Vulnerable code:** ```python def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Generate a workflow automation blueprint.") parser.add_argument("--input", required=False, help="Path to JSON input.") parser.add_argument("--output", required=True, help="Path to output artifact.") parser.add_argument("--format", choices=["json", "md", "csv"], default="json") parser.add_argument("--dry-run", action="store_true", help="Run without side effects.") return parser.parse_args() ``` ```python def render(result: dict, output_path: Path, fmt: str) -> None: output_path.parent.mkdir(parents=True, exist_ok=True) if fmt == "json": output_path.write_text(json.dumps(result, indent=2), encoding="utf-8") return if fmt == "md": details = result["details"] lines = [ f"# {result['summary']}", "", f"- status: {result['status']}", f"- workflow_name: {details['workflow_name']}", f"- trigger: {details['trigger']}", "", "## Steps", ] for step in details["steps"]: lines.append(f"- {step['order']}. {step['name']} ({step['type']})") output_path.write_text("\n".join(lines) + "\n", encoding="utf-8") return with output_path.open("w", newline="", encoding="utf-8") as handle: writer = csv.DictWriter(handle, fieldnames=["order", "name", "type", "on_failure"]) writer.writeheader() writer.writerows(result["details"]["steps"]) ``` ```python render(result, Path(args.output), args.format) ``` ### Technical Analysis The `--dry-run` o ...[truncated 1720 chars]
- Remediation
- ## Remediation Suggestions - Enforce dry-run behavior before invoking the rendering function: ```python if args.dry_run: print(json.dumps(result, indent=2)) return 0 render(result, validated_output_path, args.format) ``` - Resolve the output path and require it to remain within a dedicated output directory or approved workspace. - Reject absolute paths and parent-directory traversal when arbitrary destinations are unnecessary. - Detect and reject symbolic-link targets where symlink following is not intended. - Avoid silent truncation. Use exclusive creation mode for new artifacts or require an explicit `--force` option before overwriting an existing file. - Add automated tests confirming that `--dry-run` neither creates directories nor creates, modifies, or truncates files.
