T09 · Insecure Skill Coding Practices
- Location
scripts/sync-to-markdown.sh:58- Finding
Symbolic-Link File Overwrite in Markdown Synchronization
- Content
View full analysis
"$FILEPATH" << EOF ``` ### Technical Analysis The output directory can be selected through either the `VOICENOTES_OUTPUT_DIR` environment variable or the `--output-dir` argument. The script then writes generated Markdown using ordinary shell redirection. Shell redirection follows an existing symbolic link at `FILEPATH`. The script does not verify that: - The output directory is trusted and not writable by another user. - The destination is a regular file rather than a symbolic link. - The canonical destination remains inside the intended output directory. - The destination is owned by the current user. - File creation uses no-follow or exclusive-create protections. The generated filename is derived from a note's date and sanitized title. If an attacker can predict that filename and create a symbolic link in the selected output directory, the subsequent redirection will truncate and replace the symlink target. ### Attack Path 1. The victim configures the Skill to write into a shared or attacker-writable output directory. 2. The attacker predicts a generated filename from a note date and title, or observes a filename from an earlier synchronization. 3. The attacker creates that filename as a symbolic link pointing to another file writable by the victim: ```bash ln -s /path/to/victim-writable-target shared-output/2024-01-15-Note-Title.md ``` 4. The victim runs: ```bash ./scripts/sync-to-markdown.sh --output-dir shared-outpu ...[truncated 1066 chars]- Remediation
View remediation
&2 exit 1 fi ``` 2. Require the output directory to be a real, trusted directory and validate its canonical path: ```bash OUTPUT_DIR=$(realpath -- "$OUTPUT_DIR") [[ -d "$OUTPUT_DIR" ]] || exit 1 ``` 3. Do not use shared or untrusted writable directories. Create a private directory with restrictive permissions: ```bash mkdir -p -- "$OUTPUT_DIR" chmod 700 -- "$OUTPUT_DIR" ``` 4. Create output through a securely generated temporary file in the validated destination directory: ```bash TMPFILE=$(mktemp --tmpdir="$OUTPUT_DIR" '.voicenotes.XXXXXX') || exit 1 chmod 600 "$TMPFILE" ``` 5. Write the complete Markdown document to the temporary file, verify that the final destination is not a symbolic link, and then perform an atomic rename. 6. For robust no-follow protection, use a helper that opens the destination with operating-system protections such as `O_NOFOLLOW` and, where appropriate, `O_EXCL`. A separate pre-write symlink check alone can be vulnerable to a time-of-check/time-of-use race. 7. Refuse operation when the destination directory is writable by untrusted users unless an explicit unsafe override is provided. ]]>
