T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/humanize.sh:58
- Finding
- Path Traversal in Style Template Selection Permits Arbitrary Markdown File Reads<![CDATA[ ## Vulnerability Details **File Location**: `scripts/humanize.sh:58-62, 161-166` **Vulnerability Type**: Path traversal and unrestricted local file read **Risk Level**: Medium ### Vulnerable Code ```bash # Validate style TEMPLATE="$BASE_DIR/templates/${STYLE}.md" if [[ ! -f "$TEMPLATE" ]]; then echo "❌ Unknown style: $STYLE" echo "Available: zhihu, xiaohongshu, gongzhonghao, pengyouquan, casual" exit 1 fi ``` ```bash PROMPT=$(cat <<PROMPT_END You are a Chinese text-editing expert. Convert the following mechanical AI-generated text into a natural human writing style. Target style: $(head -1 "$TEMPLATE" | sed 's/^# *//') Style reference: $(cat "$TEMPLATE") ``` ### Technical Analysis The `STYLE` command-line value is inserted directly into a filesystem path. Although the documentation identifies only five supported styles, the implementation does not enforce that allowlist or reject path separators. The `-f` check only verifies that the resolved path exists as a regular file. It does not verify that the canonical path remains under `scripts/templates`. Because `.md` is appended automatically, an attacker can use traversal sequences to select another readable Markdown file outside the template directory. Both `head` and `cat` subsequently read the attacker-selected file and insert its contents into the generated prompt. ### Attack Path 1. Identify or predict a readable Markdown file accessible to the process. 2. Supply a traversal sequence as the style, for example: ```bash ./scripts/humanize.sh \ --input article.txt \ --style ../../../private/notes ``` 3. The constructed path becomes equivalent to: ```text scripts/templates/../../../private/notes.md ``` 4. If that file exists, it passes the regular-file check. 5. The script reads its first line with `head` and its complete contents with `cat`. 6. The contents are disclosed through standard output or copied into the file selected with `--output`. ### Impa ...[truncated 507 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Enforce the documented style allowlist before constructing a path: ```bash case "$STYLE" in zhihu|xiaohongshu|gongzhonghao|pengyouquan|casual) ;; *) printf 'Unsupported style: %s\n' "$STYLE" >&2 exit 1 ;; esac TEMPLATE="$BASE_DIR/templates/$STYLE.md" ``` For defense in depth: 1. Reject values containing `/`, `\`, `..`, control characters, or leading dots. 2. Resolve the template and template-directory paths with `realpath`. 3. Verify that the resolved file starts with the canonical template-directory path. 4. Do not use file existence as a substitute for authorization. 5. Add regression tests covering absolute paths, traversal sequences, nested traversal, symbolic links, and unsupported style names. ]]>
