T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/split.py:42
- Finding
- Predictable Output Paths Permit File Truncation and Symlink-Based Overwrite## Vulnerability Details **File Location**: `scripts/split.py`, lines 42–44 **Vulnerability Type**: Unsafe file creation and symbolic-link following **Risk Level**: Medium ```python part_path = f"{prefix}{part_num:03d}" with open(part_path, 'wb') as out: out.write(chunk) ``` ### Technical Analysis The script creates output files using a predictable, sequential naming scheme such as `x000`, `x001`, and `x002`. It opens each path in `wb` mode without checking whether the path already exists or is a symbolic link. The `wb` mode truncates an existing file before writing. It also follows symbolic links under normal filesystem semantics. Consequently, an attacker who can create files or links in the output directory can make a predictable output path refer to another file writable by the user running the Skill. The script will then truncate and replace content in that target with a fragment of the selected input file. A caller-supplied prefix can alter the destination path, but the documented default is sufficient for exploitation when an attacker controls or shares the current working directory. ### Attack Path 1. The attacker obtains write access to the directory from which the victim will run the Skill. 2. The attacker predicts the first output name, which is `x000` when the default prefix is used. 3. The attacker creates `x000` as a symbolic link to a target file that the victim is permitted to write. 4. The victim invokes the split tool with its default output prefix. 5. The script opens `x000` using `wb`, follows the symbolic link, and truncates the linked target. 6. The script writes the first input fragment into the target file, corrupting or replacing its prior content. The same destructive behavior applies to pre-existing ordinary files whose names collide with generated output paths, even without a symbolic link. ### Impact Assessment Exploitation does not directly ...[truncated 640 chars]
- Remediation
- ## Remediation Suggestions - Create output files exclusively so existing paths cannot be silently truncated, for example with `open(part_path, "xb")`. - Reject existing output paths and symbolic links, and terminate with a clear error rather than overwriting them. - Write fragments into a dedicated output directory created with restrictive permissions. - Resolve and validate the output directory and ensure generated paths remain inside it. - If replacement is an intended feature, require an explicit overwrite option and still defend against symbolic-link attacks. - For stronger race-condition resistance on supported platforms, use low-level file creation with `os.open` and flags such as `O_CREAT | O_EXCL | O_WRONLY`, plus `O_NOFOLLOW` where available, then wrap the descriptor with `os.fdopen`. - Avoid performing a separate check followed by a normal `open`, because that introduces a time-of-check-to-time-of-use race.
