T09 · Insecure Skill Coding Practices
- Location
scripts/batch_image.py:308- Finding
Output Path Traversal in the Rename Command
- Content
View full analysis
Vulnerability Details
File Location:
scripts/batch_image.py:308-317
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: Mediumpython if date_format: try: mtime = datetime.fromtimestamp(f.stat().st_mtime) new_name = mtime.strftime(date_format) + f.suffix except: new_name = f"{prefix}{start + i - 1:04d}{f.suffix}" else: new_name = f"{prefix}{start + i - 1:04d}{f.suffix}" output_file = output_path / new_name img.save(output_file)Technical Analysis
The user-controlled
--prefixand--date-formatarguments are incorporated intonew_namewithout validating whether the resulting value is a safe filename. The code does not reject absolute paths, path separators, or parent-directory components such as...With
pathlib, joining an output directory to an absolute path discards the original output directory. A relative name containing traversal components can similarly resolve outside the intended directory. The resulting path is passed directly toimg.save(), which writes the processed image and can overwrite an existing file.No canonical-path containment check is performed before the write. The broad exception handler around
strftime()does not address this issue and may instead fall back to the equally unvalidated prefix.Attack Path
- An attacker or untrusted caller supplies a crafted
--prefixor--date-format. - The supplied value produces an absolute filename or a filename containing parent-directory traversal components.
- The application joins that value to
output_pathwithout sanitization. - The resulting destination resolves outside the configured output directory.
img.save(output_file)creates or overwrites an image file at that destination.
Exploitation is limited by filesystem permissions, the existence of required parent ...[truncated 536 chars]
- An attacker or untrusted caller supplies a crafted
- Remediation
View remediation
Remediation Suggestions
- Treat generated names strictly as basenames and reject absolute paths.
- Reject
/,\,.., null characters, and platform-specific reserved filename patterns in--prefixand formatted date output. - Resolve the candidate destination and verify that it remains under the resolved output directory before writing.
- Use a conservative filename allowlist, such as letters, digits, underscores, hyphens, and periods.
- Refuse to overwrite existing files by default, or require an explicit overwrite option.
- Replace broad exception handling with specific exceptions and report invalid date formats clearly.
- Consider generating the final filename internally rather than treating formatting arguments as unrestricted path fragments.
A containment check should compare canonical paths, for example by resolving the output directory and candidate destination and then using
relative_to()to confirm that the destination is a descendant of the output directory.
