T09 · Insecure Skill Coding Practices
Warning
- Location
- fetch-data.sh:10
- Finding
- Predictable CoinGecko data file permits symlink-based overwrite<![CDATA[ ## Vulnerability Details **File Location**: `fetch-data.sh:10-16` **Vulnerability Type**: Predictable temporary file and unsafe file overwrite **Risk Level**: Medium ### Vulnerable Code ```bash # 获取数据 DATA=$(curl -s "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=$COIN_IDS&order=market_cap_desc&sparkline=false&price_change_percentage=24h") echo "$DATA" > /tmp/coins.json # 检查数据是否获取成功 if [ -s /tmp/coins.json ]; then echo "数据获取成功" ``` ### Technical Analysis The script writes API data to the fixed, globally predictable path `/tmp/coins.json`. Shell output redirection follows symbolic links and overwrites an existing target. On a multi-user system, another local user can create `/tmp/coins.json` as a symbolic link before the Skill runs. If the linked target is writable by the account executing the Skill, the script overwrites that target with the CoinGecko response. The nonempty-file check does not verify ownership, file type, or whether the path is a symbolic link. The same unsafe behavior is prescribed in `SKILL.md:17-22`, where fixed `/tmp/coins_part1.json` and `/tmp/coins_part2.json` paths are used. ### Attack Path 1. A local attacker predicts that the Skill will write `/tmp/coins.json`. 2. 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/coins.json ``` 3. The victim executes `fetch-data.sh`. 4. The shell follows the symbolic link during `echo "$DATA" > /tmp/coins.json`. 5. The linked file is truncated and replaced with the API response. ### Impact Assessment An attacker can overwrite or corrupt files writable by the account running the Skill. This may cause denial of service, application configuration corruption, or report-data manipulation. The flaw does not independently allow overwriting files that the executing account lacks permission to modify, and no privilege escalation beyond that account was demonstrated. ]]>
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create a private temporary directory with restrictive permissions: ```bash TMP_DIR=$(mktemp -d) || exit 1 chmod 700 "$TMP_DIR" trap 'rm -rf "$TMP_DIR"' EXIT DATA_FILE="$TMP_DIR/coins.json" ``` - Write only inside that private directory rather than directly under `/tmp`. - Quote every path and verify that the output is a regular file owned by the current user. - Use `curl --fail --show-error --location` with connection and overall timeouts. - Write to a newly created temporary file and atomically rename it after JSON and schema validation. - Update the corresponding commands in `SKILL.md` so the documented workflow does not reintroduce fixed temporary paths. ]]>
