T05 · Unauthorized Access and Privilege Escalation
- Location
batch_renamer.py:120- Finding
Untrusted Backup Data Allows Arbitrary Filesystem Renames
- Content
View full analysis
Vulnerability Details
File Location:
batch_renamer.py:20-22andbatch_renamer.py:120-131
Vulnerability Type: Unvalidated backup paths and missing directory-containment enforcement
Risk Level: HighVulnerable Code
python def load_backup(self): if self.backup_file.exists(): with open(self.backup_file, 'r', encoding='utf-8') as f: self.backup_data = json.load(f) return self.backup_datapython # Reverse the mappings to undo the operation reverse_mappings = {v: k for k, v in backup.items()} count = 0 for new_str, old_str in reverse_mappings.items(): new_path = Path(new_str) old_path = Path(old_str) if new_path.exists() and not old_path.exists(): new_path.rename(old_path) print(f"Undo: {new_path.name} -> {old_path.name}") count += 1Technical Analysis
The undo implementation treats
.batch-renamer-backup.jsonas trusted input. It deserializes arbitrary JSON and converts its keys and values directly into filesystem paths without validating the data structure, confirming that the paths belong to a previous operation, or ensuring that they remain inside the selected directory.Both absolute paths and paths containing traversal components can consequently be used as rename sources or destinations. The operation executes with all filesystem privileges held by the user running the utility.
The
exists()checks do not establish trust or containment. They only require the attacker-selected source to exist and the attacker-selected destination not to exist.Attack Path
- An attacker obtains write access to a directory that a victim is likely to process, such as a shared working directory.
- The attacker creates
.batch-renamer-backup.jsoncontaining a mapping whose value is the path of an existing victim-accessible file and whose key is an attacker-selected destination. - The victim runs:
...[truncated 771 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate that the backup is a JSON object containing only expected string-to-string mappings.
- Canonicalize the selected directory and every source and destination with
Path.resolve(). - Require both paths to be direct children of the selected directory.
- Reject absolute paths, traversal components, symbolic-link escapes, and unexpected nested paths.
- Store only filenames rather than unrestricted filesystem paths.
- Add an integrity mechanism or securely controlled state directory so that an attacker cannot replace the backup unnoticed.
- Before undoing, verify that each mapping corresponds to a successfully completed operation.
- Abort the entire undo transaction if any mapping fails validation rather than partially processing the file.
