T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/alerts.sh:31
- Finding
- Predictable Temporary File Allows Symlink-Based File Modification## Vulnerability Details **File Location**: `scripts/alerts.sh`, lines 31–32 and 40 **Vulnerability Type**: Predictable temporary file and unsafe symbolic-link handling **Risk Level**: Medium **Vulnerable Code**: ```bash SEEN_FILE="/tmp/prism_seen_tokens.txt" touch "$SEEN_FILE" # ... echo "$TOKEN" >> "$SEEN_FILE" ``` ### Technical Analysis The `watch` command stores token identifiers in the fixed path `/tmp/prism_seen_tokens.txt`. Because `/tmp` is normally writable by all local users, another user can create this path before the script runs. Neither `touch` nor the append redirection verifies that the destination is a regular file owned by the current user. Both operations follow symbolic links. Consequently, an attacker can replace the expected state file with a symbolic link to another file that the user running the Skill is permitted to modify. The content written to the target is derived from contract identifiers returned by the configured PRISM API. This limits direct control over the appended data when the default service is used. However, the script also permits `PRISM_URL` to be overridden, so a caller who controls that configuration and an API endpoint could influence the appended token strings. ### Attack Path 1. A local attacker predicts the fixed state-file path `/tmp/prism_seen_tokens.txt`. 2. Before the victim starts watch mode, the attacker creates a symbolic link at that path pointing to a file writable by the victim: ```bash ln -s /path/to/victim-writable-file /tmp/prism_seen_tokens.txt ``` 3. The victim runs: ```bash ./scripts/alerts.sh watch ``` 4. `touch "$SEEN_FILE"` follows the symbolic link. 5. When an unseen token is returned, `echo "$TOKEN" >> "$SEEN_FILE"` follows the link and appends the token identifier to the attacker's chosen target. 6. If the script is unnecessarily run with elevated privileges, the writable target scope expands to files accessible by ...[truncated 881 chars]
- Remediation
- ## Remediation Suggestions - Replace the predictable path with a securely created file: ```bash SEEN_FILE="$(mktemp "${TMPDIR:-/tmp}/prism_seen_tokens.XXXXXX")" || exit 1 chmod 600 "$SEEN_FILE" trap 'rm -f -- "$SEEN_FILE"' EXIT INT TERM ``` - If state must persist across invocations, use a private per-user state directory such as `${XDG_STATE_HOME:-$HOME/.local/state}/prism-alerts`, create it with mode `0700`, and create the state file with mode `0600`. - Before using a persistent state file, verify that it is a regular file, is owned by the current user, and is not a symbolic link. - Use exact fixed-string matching for token deduplication: ```bash grep -Fqx -- "$TOKEN" "$SEEN_FILE" ``` - Never run this script with elevated privileges; its functionality requires only ordinary user privileges and outbound HTTPS access. - Consider validating contract identifiers before storing them and restricting `PRISM_URL` to trusted HTTPS endpoints when overrides are not operationally necessary.
