T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/mentx-api.sh:111
- Finding
- Path Traversal Enables Unauthorized File Read and Deletion<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mentx-api.sh`, lines 111-130 **Vulnerability Type**: Unvalidated path component and path traversal **Risk Level**: High ### Vulnerable Code ```bash check_task_status() { local task_id="$1" local status_file="$TEMP_DIR/${task_id}.status" local result_file="$TEMP_DIR/${task_id}.result" if [ ! -f "$status_file" ]; then echo "{\"status\": \"not_found\", \"message\": \"任务不存在\"}" return fi local status=$(cat "$status_file") if [ "$status" = "completed" ]; then # 读取结果并返回 local result=$(cat "$result_file") echo "{\"status\": \"completed\", \"result\": $result}" # 清理临时文件 rm -f "$status_file" "$result_file" else echo "{\"status\": \"running\", \"message\": \"报告正在生成中,请稍候...\"}" fi } ``` ### Technical Analysis The `task_id` argument is supplied by the caller and inserted directly into two filesystem paths: ```bash "$TEMP_DIR/${task_id}.status" "$TEMP_DIR/${task_id}.result" ``` No allowlist validation, canonicalization, or containment check is performed. A task ID containing sequences such as `../` can therefore cause the paths to resolve outside `/tmp/mentx-doctor`. The function reads the selected status file. If its content is `completed`, it reads the corresponding result file, returns its contents, and deletes both files. The issue affects the `check` action directly and can also be reached through the polling functionality. The attack is constrained to paired paths whose final names end in `.status` and `.result`, but this does not prevent unauthorized access where such paired files exist or can be prepared. ### Attack Path 1. A local attacker identifies or creates a readable target pair such as `/tmp/target.status` and `/tmp/target.result`. 2. The attacker places `completed` in `/tmp/target.status`. 3. The attacker invokes: ```bash ./scripts/mentx-api.sh check "../target" ``` 4. The generated paths resolve as follows: ```te ...[truncated 790 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Enforce a strict allowlist before using a task ID: ```bash if [[ ! "$task_id" =~ ^mentx_[0-9]+_[0-9]+$ ]]; then echo '{"status":"error","message":"Invalid task ID"}' return 1 fi ``` 2. Reject path separators and traversal components explicitly. 3. Resolve each candidate path to a canonical path and verify that it remains under the expected task directory. 4. Store a server-generated mapping between opaque task IDs and internally created file paths rather than deriving paths from caller input. 5. Avoid deleting files based solely on an externally supplied identifier. 6. Check file ownership and reject symbolic links before reading or deleting any task file. ]]>
