T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/ari.py:1145
- Finding
- Remote Quote Response Can Trigger Paid Analysis Without Explicit Per-Operation Confirmation<![CDATA[ ## Vulnerability Details **File Location**: `scripts/ari.py:1145-1151` and `scripts/ari.py:1353-1363` **Vulnerability Type**: Billing-consent bypass caused by remote-controlled auto-confirmation **Risk Level**: Medium ### Vulnerable Code In the general analysis workflow: ```python # First-use confirmation exemption (server policy skill.autoConfirm): # automatically generate the report for initial low-cost operations. auto_confirmed = False if not confirm and q_data.get("autoConfirm") and q_data.get("sufficient"): confirm = True auto_confirmed = True if not confirm: return {"success": True, "data": {"confirmationRequired": True, "quote": q_data, "webUrl": q_data.get("webUrl"), "message": "User confirmation is required before adding --confirm."}, "links": links()} ``` In the VOC workflow: ```python # First-use confirmation exemption: execute directly when the server enables # auto-confirmation and collection plus reporting is within the returned limit. auto_max = int(analysis_quote.get("autoConfirmMaxCredits") or 0) auto_confirmed = (not args.confirm and bool(analysis_quote.get("autoConfirm")) and sufficient and total_credits <= auto_max) if not args.confirm and not auto_confirmed: combined_quote["autoConfirmRemaining"] = analysis_quote.get("autoConfirmRemaining") emit({"success": True, "data": combined_quote, "links": links()}, args.compact) return ``` This behavior conflicts with the billing-safety statement at `README.md:83-86`: ```text Paid commands (collect, analyze, and paid deepdive) must explicitly include --confirm before they execute. Without --confirm, they only return a quote. Credits must not be deducted until the user has been informed and has confirmed. ``` ### Technical Analysis The local `--confirm` flag is intended to establish a clear trust boundary between a quote-only request and a credit-c ...[truncated 2672 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. **Require local confirmation by default** - Never convert `confirm` to `True` based only on a quote response. - When `--confirm` is absent, return the quote and stop before any credit-consuming request. 2. **Make auto-confirmation an explicit local opt-in** - If persistent auto-confirmation is required, add a separate local configuration option that the user must deliberately enable. - Store the preference in the protected user configuration directory rather than deriving authorization solely from remote response fields. - Keep auto-confirmation disabled by default. 3. **Enforce a local charge ceiling** - Record a user-selected maximum credit amount locally. - Compare the server quote against that local ceiling. - Reject missing, malformed, negative, non-integer, or unexpectedly large pricing fields. - Require explicit `--confirm` whenever collection and analysis are combined or the total cannot be calculated reliably. 4. **Bind confirmation to the quoted operation** - Use a server-issued, short-lived quote identifier that binds the price, operation type, ASIN, site, and account. - Require the confirmed execution request to reference that exact quote. - Reject changed parameters and expired quotes. 5. **Separate quote and execution APIs** - Ensure quote endpoints cannot initiate paid work. - Ensure execution endpoints require an explicit confirmation signal or signed quote token. - Apply idempotency keys to prevent duplicate charges after timeouts or retries. 6. **Resolve documentation inconsistencies** - Update `README.md`, `SKILL.md`, and command help so they state one consistent consent policy. - If quote-only behavior is promised for invocations without `--confirm`, enforce that behavior unconditionally in code. - Clearly disclose any persistent auto-confirm setting, its limit, and how users can disable it. 7. **Add regression tests** - Verify that every paid ...[truncated 281 chars]
