T09 · Insecure Skill Coding Practices
- Location
scripts/export-subs.sh:24- Finding
Unrestricted Export Path Allows Arbitrary File Overwrite
- Content
View full analysis
"$OUTPUT_FILE" ``` ```bash # Markdown export OUTPUT_FILE="${CUSTOM_OUTPUT:-$EXPORT_DIR/$DATE_STAMP-subscriptions.md}" { # Report generation omitted } > "$OUTPUT_FILE" ``` ```bash # Budget Buddy export OUTPUT_FILE="${CUSTOM_OUTPUT:-$EXPORT_DIR/$DATE_STAMP-budget-buddy-import.json}" jq --arg date "$DATE_STAMP" --argjson mt "$MONTHLY_TOTAL" --argjson at "$ANNUAL_TOTAL" '{ source: "subscription-tracker", version: "1.0.0", exported_at: ($date + "T00:00:00Z"), monthly_recurring: [.subscriptions[] | select(.status == "active") | { name: .service, amount: .amount, category: .category, frequency: .frequency, next_charge: .next_renewal }], annual_total: $at, monthly_total: $mt }' "$DB_FILE" > "$OUTPUT_FILE" ``` ### Technical Analysis The `--output` option accepts an arbitrary path without canonicalization, destination-directory restrictions, symlink checks, or overwrite confirmation. All three export modes use the shell truncation operator (`>`), which creates the specified file or replaces its existing contents. Shell quoting prevents command injection through the path, but it does not prevent destructive file replacement. Because this script is intended to be invoked by an AI agent, a malicious statement, prompt-injection payload, or misleading user request could influence the agent into selecting a sensitive destination. The operation remains limited t ...[truncated 1529 chars]- Remediation
View remediation
&2 exit 1 ;; esac ``` 2. Reject symlink destinations and non-regular existing files: ```bash if [[ -L "$REQUESTED" ]]; then echo "Error: symlink output paths are not allowed" >&2 exit 1 fi if [[ -e "$REQUESTED" && ! -f "$REQUESTED" ]]; then echo "Error: output destination is not a regular file" >&2 exit 1 fi ``` 3. Do not overwrite existing files unless the user supplies a deliberate `--force` option and confirms the exact canonical destination. 4. Generate output atomically in a securely created temporary file inside the export directory: ```bash TMP_FILE="$(mktemp "$EXPORT_DIR/.export.XXXXXX")" chmod 600 "$TMP_FILE" # Write the complete export to "$TMP_FILE" mv -- "$TMP_FILE" "$REQUESTED" ``` 5. Set a restrictive `umask`, such as `umask 077`, before creating financial-data exports. 6. At the agent-instruction layer, require explicit user confirmation before writing outside the default export directory, even if custom external paths remain supported. ]]>
