T09 · Insecure Skill Coding Practices
- Location
scripts/pr-comment-screenshots.sh:70- Finding
Predictable temporary file permits local symlink-based file overwrite
- Content
View full analysis
/tmp/pr-comment-body.md # ── 3. Post comment ── gh pr comment "$PR_NUM" --repo "$REPO" --body-file /tmp/pr-comment-body.md echo "Comment posted to PR #$PR_NUM" # Cleanup rm -rf "$TMP" /tmp/pr-comment-body.md ``` ### Technical Analysis The script writes the generated pull-request comment to the fixed, globally predictable path `/tmp/pr-comment-body.md`. Shared temporary directories are normally writable by every local user. Although the directory commonly has the sticky bit set, that protection does not prevent another user from creating the filename before this script runs. Shell output redirection follows symbolic links. Consequently, if an attacker creates `/tmp/pr-comment-body.md` as a symbolic link to another file, the redirection can truncate and overwrite the linked file using the privileges of the account running the script. The script already creates a private temporary directory with `mktemp -d`, but it does not place the comment body inside that directory. The final `rm -rf` normally unlinks the symbolic link itself rather than deleting its target; therefore, the confirmed security consequence is target-file overwrite or truncation, not target-file deletion. ### Attack Path 1. An attacker with access to the same host anticipates that another user or automated process will execute the script. 2. The attacker creates a symbolic link at the predictable location: ```bash ln -s /path/to/victim-writable-file /tmp/pr-comment-body.md ``` 3. The victim executes `pr-comment-screenshots.sh`. 4. The shell follows the symbolic link while processing: ```bash echo -e "$BODY" > /tmp/pr-comment-body.md ``` 5. The linked file is truncated and replaced with the generated Markdown content. 6. The GitHub CLI may then rea ...[truncated 690 chars]- Remediation
View remediation
"$BODY_FILE" gh pr comment "$PR_NUM" \ --repo "$REPO" \ --body-file "$BODY_FILE" ``` Additional hardening steps: 1. Use `printf` instead of `echo -e` to avoid implementation-dependent option and escape processing. 2. Keep every temporary artifact under the private `$TMP` directory. 3. Use `trap` so cleanup also occurs on errors and signals. 4. Quote all temporary paths and place `--` before paths passed to destructive commands. 5. Run the script with only the repository and filesystem permissions required for its task. ]]>
