T09 · Insecure Skill Coding Practices
- Location
references/ofox-image.sh:2190- Finding
Billable API requests do not technically enforce prior user approval
- Content
View full analysis
Vulnerability Details
File Location:
references/ofox-image.sh:2190-2209andreferences/ofox-image.sh:2849-2868
Vulnerability Type: Missing authorization gate for billable operations
Risk Level: MediumRelevant requirement (
SKILL.md:217-220):markdown ## Before you spend: quote it, get a yes, then spend it **Never send a generation request until the user has seen a cost table and said yes.**Generation request path (
references/ofox-image.sh:2190-2209):bash print_estimate "$model" "${n:-1}" "$quality" "$size" if [ -n "$dry_run" ]; then echo "DRY RUN — nothing was submitted and nothing was billed." >&2 echo "Re-run without --dry-run to generate." >&2 echo "STATUS dry_run" echo "MODEL $model" echo "QUALITY $quality" [ -n "$size" ] && echo "SIZE $size" ... return 0 fi # --- the one and only network call --- echo "Requesting image generation from Ofox (model=$model)..." >&2 local tmp_body http_code curl_rc body tmp_body=$(mktemp) http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \ --connect-timeout "$CONNECT_TIMEOUT" --max-time "$GENERATE_MAX_TIME" \ -X POST "$API_BASE/images/generations" \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "Content-Type: application/json" \ -d "$payload")Edit request path (
references/ofox-image.sh:2849-2868):bash print_edit_estimate "$model" "${n:-1}" "$quality" "$input_measured" if [ -n "$dry_run" ]; then [ -n "$url_file" ] && rm -f "$url_file" echo "DRY RUN — nothing was submitted and nothing was billed." >&2 echo "Re-run without --dry-run to edit." >&2 echo "STATUS dry_run" ... return 0 fi # --- the one and only network call --- echo "Requesting image edit from Ofox (model=$model)..." >&2 local tmp_body http_code curl_rc body tmp_body=$(mktemp) http_code=$(curl -sS -o "$tmp_body" -w '%{http_code}' \ --connect-timeout "$CON ...[truncated 2383 chars]- Remediation
View remediation
Remediation Suggestions
Enforce the financial authorization gate in executable code rather than relying only on Skill instructions:
- Make dry-run output include a cryptographically random, short-lived quote identifier bound to the validated model, endpoint, prompt hash, quantity, quality, size, extra fields, estimated cost, and API-base origin.
- Require a matching option such as
--approve-quote <id>before any billable POST. - Reject approvals when request parameters differ from the approved quote or when the quote has expired.
- For interactive use, require a confirmation prompt that displays the final endpoint, model, quantity, and estimate immediately before submission.
- For trusted non-interactive automation, use a separately named option and require an explicit spending policy, including per-request and cumulative limits.
- Preserve the existing
--dry-runbehavior, parameter validation, and maximum quantity checks as defense-in-depth.
