T09 · Insecure Skill Coding Practices
- Location
scripts/release/stage_release.py:39- Finding
Unrestricted Recursive Deletion Through User-Controlled Staging Path
- Content
View full analysis
argparse.Namespace: parser = argparse.ArgumentParser(description='Stage a clean public release directory') parser.add_argument('--output-dir', default=str(DEFAULT_STAGE_DIR), help='Stage directory path') return parser.parse_args() def main() -> int: args = parse_args() stage_dir = Path(args.output_dir).resolve() patterns = load_patterns(IGNORE_FILE) if stage_dir.exists(): shutil.rmtree(stage_dir) stage_dir.mkdir(parents=True, exist_ok=True) ``` ### Technical Analysis The `--output-dir` argument accepts an arbitrary filesystem path. The supplied path is resolved to an absolute path and recursively deleted with `shutil.rmtree()` if it already exists. Resolving the path does not establish that it is safe. The implementation does not verify that the target is: - Under the intended `dist/release` staging directory. - Distinct from the repository root. - Distinct from the invoking user's home directory. - Distinct from a filesystem root or other sensitive directory. - A directory created by a previous execution of this utility. There is also no confirmation prompt, staging marker, or explicit destructive-operation flag. Consequently, a command-line mistake or attacker-influenced invocation can convert a release-staging operation into arbitrary directory deletion. ### Attack Path 1. An attacker, malicious instruction, or defective automation provides a command such as: ```bash python3 scripts/release/stage_release.py --output-dir /path/to/valuable/directory ``` 2. A user with write permission to that directory executes the command while preparing a release. 3. `Path.resolve()` produces the absolute target but performs no authorization or containment check. 4. Because the tar ...[truncated 963 chars]- Remediation
View remediation
