T09 · Insecure Skill Coding Practices
- Location
scripts/generate_workflow_blueprint.py:104- Finding
Dry-Run Mode Still Creates Directories and Overwrites Files
- Content
View full analysis
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: MediumVulnerable 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-runo ...[truncated 1720 chars]- Remediation
View 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
--forceoption before overwriting an existing file. -
Add automated tests confirming that
--dry-runneither creates directories nor creates, modifies, or truncates files.
-
