T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:34- Finding
Path Traversal Allows Note Files to Be Written Outside the Intended Storage Directory
- Content
View full analysis
\"\"" echo " Example: script.sh note biology \"Mitosis has 4 phases: prophase, metaphase, anaphase, telophase\"" exit 1 fi ensure_data_dir local subject_dir="${NOTES_DIR}/${subject}" mkdir -p "${subject_dir}" local ts ts="$(timestamp)" local filename="${subject_dir}/$(today).md" # Append to the day's note file { echo "" echo "## ${ts}" echo "" echo "${content}" echo "" } >> "${filename}" ``` ### Technical Analysis The `note` command treats the user-controlled `subject` argument as a trusted directory name. It concatenates that value directly with `${NOTES_DIR}` and passes the resulting path to `mkdir -p`: ```bash local subject_dir="${NOTES_DIR}/${subject}" mkdir -p "${subject_dir}" ``` The implementation does not reject path separators, `..` components, or paths that traverse symbolic links. Consequently, a subject such as `../../escaped` resolves outside the documented `~/.student/notes/` storage boundary. After creating the directory, the command constructs a date-based Markdown filename under the traversed path and appends attacker-controlled note content to it. Shell quoting prevents command injection, but it does not prevent filesystem path traversal. Pre-existing symbolic links beneath the notes directory may also redirect the write to another location because the implementation neither rejects symlinks nor verifies the canonical destination before opening the file. ### Attack Path 1. An attacker or untrusted caller invokes the Skill with a traversal sequence as the subject: ```bash bash ...[truncated 1522 chars]- Remediation
View remediation
&2 exit 1 fi ``` 2. **Explicitly reject path syntax.** Reject `/`, `\`, standalone `.` or `..` components, control characters, and newline characters. 3. **Verify the canonical destination.** Resolve both the notes root and destination with a reliable canonicalization mechanism, then ensure the destination remains beneath the canonical notes root before creating or writing files. 4. **Defend against symbolic-link traversal.** Reject pre-existing symlink components or open files using an implementation that supports no-follow semantics. Canonical-path validation alone should not be relied upon where another process can change path components between validation and use. 5. **Apply restrictive permissions.** Create the data directory with user-only permissions where appropriate: ```bash umask 077 mkdir -p -- "${NOTES_DIR}" ``` 6. **Use `--` for path-taking commands.** Although this does not prevent traversal, it prevents option interpretation for paths beginning with a hyphen: ```bash mkdir -p -- "${subject_dir}" ``` 7. **Add regression tests** covering `../`, nested traversal, slashes, symbolic links, control characters, and valid subject identifiers. Tests should verify that every resulting note path remains under `~/.student/notes/`. ]]>
