T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/strip.py:226
- Finding
- Manifest Output Can Silently Overwrite Arbitrary Writable Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/strip.py:226-231` and `scripts/strip.py:369-377` **Vulnerability Type**: Unrestricted file overwrite through a user-controlled manifest path **Risk Level**: Medium ### Vulnerable Code ```python def write_manifest(path: Path, reports: list[FileReport]) -> None: path.parent.mkdir(parents=True, exist_ok=True) path.write_text( json.dumps([asdict(report) for report in reports], indent=2), encoding="utf-8", ) ``` ```python manifest_path = None if args.manifest: manifest_path = Path(args.manifest) if not manifest_path.is_absolute(): if batch: manifest_path = output_root / manifest_path else: first_output = reports[0].output manifest_path = (Path(first_output).parent if first_output else src.parent) / manifest_path if not args.dry_run: write_manifest(manifest_path, reports) ``` ### Technical Analysis The value accepted by `--manifest` directly controls the destination passed to `Path.write_text()`. This method opens the destination for writing and truncates an existing file. The manifest-writing code does not perform any of the protections applied to image outputs: - It does not reject an existing destination unless overwrite permission was explicitly provided. - It does not prevent the manifest from targeting the input image or another user file. - It does not reject symbolic links. - It does not use exclusive file creation. - It accepts absolute paths and resolves relative paths into writable output locations. Consequently, any existing file writable by the process can be replaced with the generated JSON report. If the destination is a symbolic link, the write can follow that link and overwrite its target. This issue does not independently elevate privileges: the process must already have permission to write the selected target. However, it violates the documented expectation that destructive overwr ...[truncated 1323 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Refuse to overwrite an existing manifest by default and require an explicit `--overwrite` option. 2. Open new manifest files using exclusive creation mode: ```python with path.open("x", encoding="utf-8") as handle: json.dump(data, handle, indent=2) ``` 3. Reject symbolic-link destinations before writing. Where supported, use operating-system flags such as `O_NOFOLLOW` to reduce time-of-check/time-of-use risks. 4. Resolve and validate the manifest destination against an explicitly permitted output directory when arbitrary destinations are unnecessary. 5. Reject a manifest path that resolves to the input image or an image output. 6. Write through a securely created temporary file in the same destination directory and atomically replace the final path only when overwrite was explicitly authorized. 7. Add tests covering existing files, symbolic links, input-file collisions, output-file collisions, absolute paths, and concurrent destination creation. ]]>
