T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/edge-tts.sh:5
- Finding
- Predictable Temporary Output Path Enables File Clobbering and Cross-Request Data Exposure## Vulnerability Details **File Location**: `scripts/edge-tts.sh`, lines 5–13 **Vulnerability Type**: Predictable temporary file path and unsafe output handling **Risk Level**: Medium ### Vulnerable Code ```bash OUTPUT="${2:-/tmp/edge-tts-output.mp3}" VOICE="${3:-zh-CN-XiaoxiaoNeural}" if [[ -z "$TEXT" ]]; then echo "Usage: edge-tts.sh \"文本\" [输出文件] [声音]" >&2 exit 1 fi edge-tts --voice "$VOICE" --text "$TEXT" --write-media "$OUTPUT" ``` ### Technical Analysis When the caller does not provide an output path, every invocation writes to the fixed, predictable path `/tmp/edge-tts-output.mp3`. Shared temporary directories are generally writable by other local users and processes. An attacker who can write to `/tmp` may pre-create the destination as a symbolic link. If `edge-tts` follows that link when opening its output, generated audio could overwrite a different file writable by the account running the Skill. The script does not verify whether the destination is a symbolic link, create the file atomically, or place it in a private directory. The fixed path also causes concurrent invocations to share one file. One request may overwrite another request's output, receive another user's generated speech, or send partially written or corrupted audio. Shell command injection is not indicated here because `TEXT`, `VOICE`, and `OUTPUT` are passed as quoted arguments. ### Attack Path 1. A local attacker obtains write access to the shared `/tmp` directory, which is typical on multi-user systems. 2. The attacker removes or waits for the absence of `/tmp/edge-tts-output.mp3`. 3. The attacker creates `/tmp/edge-tts-output.mp3` as a symbolic link to a file writable by the agent's operating-system account. 4. The agent invokes `scripts/edge-tts.sh` without supplying a custom output path. 5. The script passes the predictable path to `edge-tts`. 6. If `edge-tts` follows symbolic links, it writes generated audio through the link and overwrites the selected target. F ...[truncated 890 chars]
- Remediation
- ## Remediation Suggestions - Generate a unique output file for each invocation using `mktemp`, preferably inside a private per-user runtime directory. - Apply a restrictive `umask`, such as `077`, before creating audio files. - Create the destination atomically rather than checking a predictable path and writing it later. - Reject caller-supplied destinations that are symbolic links or otherwise outside an explicitly permitted output directory. - Delete temporary audio after it has been delivered, using a cleanup trap where lifecycle permits. - Ensure each concurrent request receives a separate output path. Example hardening pattern: ```bash #!/usr/bin/env bash set -euo pipefail umask 077 TEXT="${1:-}" VOICE="${3:-zh-CN-XiaoxiaoNeural}" if [[ -z "$TEXT" ]]; then echo "Usage: edge-tts.sh \"text\" [output file] [voice]" >&2 exit 1 fi if [[ -n "${2:-}" ]]; then OUTPUT="$2" if [[ -L "$OUTPUT" ]]; then echo "Refusing to write through a symbolic link: $OUTPUT" >&2 exit 1 fi else OUTPUT="$(mktemp --tmpdir edge-tts-output.XXXXXXXX.mp3)" fi edge-tts --voice "$VOICE" --text "$TEXT" --write-media "$OUTPUT" printf '%s\n' "$OUTPUT" ``` For stronger isolation, accept outputs only within a private directory created with mode `0700`, and validate the canonical destination path before writing.
