T09 · Insecure Skill Coding Practices
- Location
scripts/habit-tracker.sh:13- Finding
Path Traversal Enables Arbitrary File Creation and Modification
- Content
View full analysis
Vulnerability Details
File Location:
scripts/habit-tracker.sh, lines 13–47
Vulnerability Type: Path traversal and unsafe file handling
Risk Level: HighVulnerable Code
bash HABIT_NAME="$1" STATUS="${2:-check}" HABIT_FILE=".learnings/habits/${HABIT_NAME}.md" DATE=$(date +%Y-%m-%d) # 创建习惯文件(如果不存在) if [ ! -f "$HABIT_FILE" ]; then mkdir -p "$(dirname "$HABIT_FILE")" cat > "$HABIT_FILE" << EOF # 习惯追踪: $HABIT_NAME **开始日期**: $(date +%Y-%m-%d) **目标频率**: [填写] **当前阶段**: 启动期 ## 每日记录 EOF echo "✅ 创建新习惯文件: $HABIT_FILE" echo "📝 请编辑文件填写习惯详细信息" fiThe completion branch subsequently appends data to the same attacker-controlled path:
bash case $STATUS in "yes"|"y"|"完成") # 记录完成 if grep -q "### $DATE" "$HABIT_FILE"; then echo "⚠️ 今天已经记录过此习惯" else cat >> "$HABIT_FILE" << EOF ### $DATE ✅ - **完成时间**: $(date +%H:%M) - **质量评分**: [1-10] - **备注**: [填写] EOFTechnical Analysis
The first command-line argument is accepted as
HABIT_NAMEand inserted directly intoHABIT_FILE. The script does not reject path separators,..components, absolute-path-like input, or symbolic-link destinations. Shell quoting prevents word splitting and shell command injection, but it does not prevent filesystem path traversal.A value such as
../../../../tmp/targetproduces a path similar to:text .learnings/habits/../../../../tmp/target.mdFilesystem path normalization resolves the
..components outside the intended.learnings/habitsdirectory. Themkdir -p,cat >,cat >>, andgrepoperations then act on the escaped destination.If the destination is not recognized as an existing regular file, the initialization branch uses
cat >, creating the file or truncating the resolved destination. If it exists, the status branches may append habit records usingcat >>. S ...[truncated 1816 chars]- Remediation
View remediation
Remediation Suggestions
-
Apply strict allowlist validation to habit names. Accept only a limited identifier format and reject all other input:
bash HABIT_NAME="$1" if [[ ! "$HABIT_NAME" =~ ^[A-Za-z0-9_-]+$ ]]; then printf '%s\n' "Error: habit names may contain only letters, numbers, underscores, and hyphens." >&2 exit 1 fi -
Use a fixed, canonical base directory. Resolve the storage directory before constructing the destination and verify that the canonical destination remains inside it.
bash BASE_DIR="$(pwd -P)/.learnings/habits" mkdir -p -- "$BASE_DIR" HABIT_FILE="$BASE_DIR/${HABIT_NAME}.md" -
Reject symbolic-link destinations.
bash if [ -L "$HABIT_FILE" ]; then printf '%s\n' "Error: symbolic-link habit files are not allowed." >&2 exit 1 fiWhere available, perform file creation through an API or utility that supports no-follow and exclusive-creation semantics to avoid check-to-use races.
-
Avoid unintended truncation. Create new files atomically and refuse to overwrite existing destinations. Ensure that append operations are performed only after validating that the destination is a regular file owned or otherwise trusted by the current user.
-
Use defensive shell settings and argument handling.
bash set -euo pipefail mkdir -p -- "$BASE_DIR" -
Add regression tests covering
../, embedded/, absolute paths, newlines, symbolic links, and names beginning with-. Each test should verify that no file outside the canonical habits directory is created or modified.
-
