T09 · Insecure Skill Coding Practices
- Location
tool.py:23- Finding
Non-Atomic Destination Check Can Cause Existing Files to Be Overwritten
- Content
View full analysis
Vulnerability Details
File Location:
tool.py, lines 23–34
Vulnerability Type: Time-of-check to time-of-use race condition
Risk Level: MediumVulnerable Code:
python if new_path == path: return False # No change needed if os.path.exists(new_path): print(f"Conflict: {new_path} already exists. Skipping '{os.path.basename(path)}'.", file=sys.stderr) return False try: os.rename(path, new_path) print(f"Renamed: '{os.path.basename(path)}' → '{new_name}'") return True except OSError as e: print(f"Error renaming '{os.path.basename(path)}': {e}", file=sys.stderr) return FalseTechnical Analysis
The destination existence check and the subsequent rename are separate filesystem operations. The destination can therefore change after
os.path.exists(new_path)returnsFalsebut beforeos.rename(path, new_path)executes.On platforms where
os.rename()replaces an existing destination, a file created during this interval may be overwritten. Consequently, the implementation does not reliably satisfy its stated guarantee of avoiding overwrites. Exploitation requires the attacker to have write access to the directory being processed and sufficient ability to win or repeatedly attempt the race.Attack Path
- A victim runs the filename-cleaning tool against a directory writable by an attacker.
- The tool derives a sanitized destination name from an existing filename.
- The tool checks
os.path.exists(new_path)and observes that the destination does not exist. - Before
os.rename()executes, the attacker creates a file atnew_path. - On a platform with replacement semantics,
os.rename()replaces the attacker's newly created destination with the source file. - The destination's prior contents are lost.
Impact Assessment
The issue can cause local file replacement and data loss within directories where both the victim process and ...[truncated 321 chars]
- Remediation
View remediation
Remediation Suggestions
Use an atomic no-replace operation rather than checking for existence before renaming. On Linux, an implementation may use
renameat2()withRENAME_NOREPLACE; equivalent platform-specific primitives should be used elsewhere.If portability is required, implement a carefully reviewed strategy that atomically reserves the destination and handles rollback without exposing another check-to-use interval. Treat symbolic links and all unexpected filesystem object types as conflicts. Clearly document any platform on which overwrite prevention cannot be guaranteed, and add concurrent filesystem tests that attempt to create the destination during the rename operation.
