T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/task.sh:104
- Finding
- Predictable Temporary File Allows Symlink-Based File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/task.sh:93-105` and `scripts/task.sh:139-151` **Vulnerability Type**: Predictable temporary file and unsafe symbolic-link handling **Risk Level**: Medium ### Vulnerable Code ```bash jq --arg title "$title" --arg priority "$priority" --arg due "$due" --arg tags "$tags" --arg now "$now" --argjson id "$id" --argjson w "$w" ' .tasks += [{ id:$id, title:$title, status:"open", priority:$priority, priorityWeight:$w, due:$due, tags:($tags|split(",")|map(gsub("^[[:space:]]+|[[:space:]]+$";"")|select(length>0))), createdAt:$now, updatedAt:$now }] | .nextId += 1 ' "$DB" > "$DB.tmp" && mv "$DB.tmp" "$DB" ``` The update operation uses the same predictable path: ```bash jq --argjson id "$id" --arg status "$status" --arg priority "$priority" --arg due "$due" --arg title "$title" --arg now "$now" --argjson w "$w" ' .tasks |= map(if .id==$id then .status = (if $status=="" then .status else $status end) | .priority = (if $priority=="" then .priority else $priority end) | .priorityWeight = (if $priority=="" then .priorityWeight else $w end) | .due = (if $due=="" then .due else $due end) | .title = (if $title=="" then .title else $title end) | .updatedAt = $now else . end) ' "$DB" > "$DB.tmp" && mv "$DB.tmp" "$DB" ``` ### Technical Analysis Both database mutation paths write to the fixed filename `data/tasks.json.tmp`. Shell output redirection follows symbolic links. Consequently, a local attacker who can write to the `data` directory can pre-create `tasks.json.tmp` as a symbolic link to another file. When a more privileged user or automated Agent invokes an `add`, `update`, or `done` operation, the shell opens and truncates the symbolic-link target before `jq` executes. The generated JSON is then written to that target. The subsequent `mv` does not undo the corruption. The fixed temporary filename also makes concurrent operations unsafe. Tw ...[truncated 1342 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Create a unique temporary file in the database directory with `mktemp`, for example: ```bash tmp="$(mktemp "$BASE_DIR/data/.tasks.json.XXXXXX")" trap 'rm -f -- "$tmp"' EXIT jq ... "$DB" > "$tmp" chmod 600 "$tmp" mv -- "$tmp" "$DB" trap - EXIT ``` - Keep the temporary file in the same filesystem as the database so the final rename remains atomic. - Never reuse a predictable temporary filename. - Validate that the database directory and database are not symbolic links when the deployment trust model requires this protection. - Add an exclusive lock, such as `flock`, around the complete read-modify-write sequence to prevent concurrent lost updates. - Restrict write access to the project and `data` directories to trusted accounts. ]]>
