T09 · Insecure Skill Coding Practices
Warning
- Location
- run.sh:9
- Finding
- Predictable Temporary Report Enables Symlink-Based File Overwrite## Vulnerability Details **File Location**: `run.sh:9` and `scripts/analyzer.py:613-615` **Vulnerability Type**: Unsafe predictable temporary file handling **Risk Level**: Medium ### Vulnerable Code `run.sh:9`: ```bash python3 "$SCRIPT_DIR/scripts/analyzer.py" --root "$WORKSPACE_ROOT" --output /tmp/workspace-analysis.json ``` `scripts/analyzer.py:613-615`: ```python if args.output: with open(args.output, 'w') as f: f.write(output_json) ``` ### Technical Analysis The launcher always writes its report to the fixed, shared path `/tmp/workspace-analysis.json`. The analyzer then opens that path in write mode without checking whether it is a symbolic link, verifying ownership, or creating the file exclusively. On Unix-like systems, `open(path, 'w')` follows symbolic links and truncates the resolved target. A local attacker who can create the predictable path before the victim invokes `run.sh` can replace it with a symbolic link to another file writable by the victim. The analyzer will subsequently truncate and replace that target with generated JSON. Exploitation requires local access to the shared temporary directory and a target file that the process executing the skill is permitted to write. ### Attack Path 1. A local attacker predicts the fixed output path `/tmp/workspace-analysis.json`. 2. Before the victim runs the skill, the attacker creates that path as a symbolic link to a file writable by the victim: ```bash ln -s /path/to/victim-writable-file /tmp/workspace-analysis.json ``` 3. The victim invokes `run.sh`. 4. The launcher passes the attacker-controlled symbolic-link path to `analyzer.py`. 5. `open(args.output, 'w')` follows the link and truncates the target. 6. The analyzer overwrites the target with the generated JSON report. ### Impact Assessment The attacker can cause truncation and replacement of files writable by the account running the skill. Possible consequences include configuration corruption, loss of user data, a ...[truncated 255 chars]
- Remediation
- ## Remediation Suggestions 1. Create a unique report file with `mktemp` rather than using a fixed shared path: ```bash umask 077 REPORT_FILE="$(mktemp "${TMPDIR:-/tmp}/workspace-analysis.XXXXXX.json")" || exit 1 python3 "$SCRIPT_DIR/scripts/analyzer.py" \ --root "$WORKSPACE_ROOT" \ --output "$REPORT_FILE" ``` 2. Prefer a private runtime or cache directory owned by the invoking user instead of a globally shared directory. 3. Harden file creation in Python by using exclusive creation when a new output is expected: ```python with open(args.output, "x", encoding="utf-8") as f: f.write(output_json) ``` 4. Where supported, use low-level file creation with `O_CREAT | O_EXCL | O_NOFOLLOW` and restrictive permissions such as `0600`. 5. If overwriting user-selected output files is required, use `lstat` to reject symbolic links and verify the destination's ownership and type before writing. 6. Ensure all failure paths terminate safely and do not fall back to the predictable filename.
