T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/find.sh:206
- Finding
- Predictable Persistent Temporary Report Permits Symlink-Based File Overwrite## Vulnerability Details **File Location**: `scripts/find.sh:206` **Vulnerability Type**: Predictable temporary file and unsafe destination handling **Risk Level**: Medium ### Vulnerable Code ```bash RESULT_FILE="${TMPDIR:-/tmp}/find-skills-$(date +%s).json"; cp "$OUT" "$RESULT_FILE" ``` ### Technical Analysis The script copies its result to a filename constructed from the current Unix timestamp. Timestamp resolution is one second, making the destination predictable. Unlike files stored in the protected directory created with `mktemp -d`, this report is written directly into `${TMPDIR:-/tmp}` and is not removed by the existing exit trap. The `cp` operation does not atomically reserve a new file and does not verify that the destination is a regular file. If an attacker can create the predicted destination as a symbolic link before the copy occurs, `cp` may follow that link and overwrite its target with the report contents. Exploitability depends on local filesystem protections, permissions, and timing. Protections such as Linux `fs.protected_symlinks` may prevent attacks between different users in a sticky shared directory, but the script should not rely on optional operating-system hardening. An attacker controlling `TMPDIR` can also direct the persistent report to an untrusted location. The report contains the user's search query, source health data, locally matched installed-skill names, and public registry metadata. Its persistence also contradicts the documentation stating that temporary files are discarded on exit. ### Attack Path 1. A local attacker determines that the victim is about to execute the Skill. 2. The attacker predicts the destination name from the current timestamp, such as `/tmp/find-skills-1750000000.json`. 3. Before line 206 executes, the attacker creates that pathname as a symbolic link to a file writable by the victim: ```bash ln -s /path/to/victim-writable-file /tmp/find-skills-175000000 ...[truncated 983 chars]
- Remediation
- ## Remediation Suggestions - Keep the report inside the already protected `$TMP` directory unless persistent output is explicitly requested. - If a persistent report is required, create it atomically with `mktemp` rather than constructing its name from a timestamp: ```bash umask 077 RESULT_FILE=$(mktemp "${TMPDIR:-/tmp}/find-skills.XXXXXXXX.json") || exit 1 cp -- "$OUT" "$RESULT_FILE" ``` - Apply `umask 077` before creating temporary artifacts so report files are readable and writable only by the invoking user. - Reject an untrusted or unsafe `TMPDIR`, or use a private runtime directory owned by the current user. - Remove the persistent report during the exit trap unless the user explicitly requests retention. - If writing to a caller-selected destination, use no-follow and exclusive-creation semantics, validate that the destination is not a symbolic link, and avoid overwriting existing files. - Update the documentation to accurately describe any report that intentionally persists after execution.
