T09 · Insecure Skill Coding Practices
- Location
scripts/acestep.sh:214- Finding
Unvalidated job identifiers permit writes outside the output directory
- Content
View full analysis
"$output_file" echo -e "${GREEN}Result saved: $output_file${NC}" } ``` ```bash if [ -n "$audio_path" ]; then local output_file="${OUTPUT_DIR}/${job_id}_${count}.${audio_format}" local download_url="${api_url}${audio_path}" echo -e " ${CYAN}Downloading audio $count...${NC}" ``` ```bash if [ -n "$audio_url" ]; then local output_file="${OUTPUT_DIR}/${job_id}_$((i+1)).${audio_format}" echo -e " ${CYAN}Decoding audio $((i+1))...${NC}" if decode_base64_audio "$audio_url" "$output_file"; then ``` ```bash local job_id job_id=$(jq -r '.id // empty' "$resp_file" 2>/dev/null) [ -z "$job_id" ] && job_id="completion-$(date +%s)" ``` The `status` command also accepts a user-supplied job identifier and eventually passes it to the same output functions: ```bash cmd_status() { check_deps local job_id="$1" [ -z "$job_id" ] && { echo -e "${RED}Error: job_id required${NC}"; echo "Usage: $0 status "; exit 1; } ``` ### Technical Analysis The script uses `job_id` directly as part of output filenames without validating that it is a single safe filename component. In normal generation flows, this value originates from an API response. In the `status` flow, it originates directly from a command-line argument. A value containing path separators or traversal components, such as `../../target`, causes the constructed path to resolve outside `OUTPUT_DIR`. The script subsequently writes result JSON, downloaded response bodies, or decoded audio data to that path. Shell quoting p ...[truncated 1635 chars]- Remediation
View remediation
&2 return 1 } [[ "$job_id" != "." && "$job_id" != ".." ]] || return 1 } ``` 2. Reject forward slashes, backslashes, traversal components, control characters, absolute paths, and empty identifiers. 3. Prefer generating a local random filename independent of the remote task identifier. Store the untrusted remote identifier only as JSON metadata. 4. Canonicalize the destination and verify containment before every write: ```bash output_root=$(realpath -m "$OUTPUT_DIR") destination=$(realpath -m "$OUTPUT_DIR/$safe_name") case "$destination" in "$output_root"/*) ;; *) echo "Error: output path escapes output directory" >&2; return 1 ;; esac ``` 5. Open output files defensively and avoid following attacker-created symbolic links where the platform permits. 6. Apply the same validation to generation responses, completion IDs, native task IDs, and `status` command arguments. ]]>
