T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/ari.py:1109
- Finding
- Remote Quote Response Can Bypass Explicit Confirmation for Paid Operations## Vulnerability Details **File Location**: `scripts/ari.py`, lines 1109–1114 and 1318–1323 **Vulnerability Type**: Server-controlled bypass of local payment confirmation **Risk Level**: Medium **Relevant code:** ```python # First-use confirmation exemption based on the server-side skill.autoConfirm policy. 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": "The user must append --confirm before generation and credit deduction."}, "links": links()} ``` ```python # First-use confirmation exemption for combined collection and report generation. 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 ``` ### Technical Analysis The CLI states at `scripts/ari.py:2–5` that paid collection and AI-analysis commands require an explicit `--confirm` flag after a free preview or quote. The implementation does not consistently enforce that local security boundary. In `run_analysis`, an unconfirmed invocation is converted into a confirmed invocation when the remote quote response contains truthy `autoConfirm` and `sufficient` fields. The combined `voc` workflow similarly proceeds without `--confirm` when the response supplies `autoConfirm` and a sufficiently large `autoConfirmMaxCredits` value. Confirmation of a ...[truncated 2020 chars]
- Remediation
- ## Remediation Suggestions 1. Require `--confirm` for every credit-consuming operation: ```python if not confirm: return quote_response ``` Do not change `confirm` based on fields returned by the remote service. 2. Remove the `autoConfirm` branches from both `run_analysis` and `cmd_voc`, or restrict automatic confirmation to a separate, explicit local opt-in mechanism. 3. If automatic spending is a required feature, store a locally established policy containing: - An explicit enabled/disabled state. - A maximum per-operation credit amount. - A maximum cumulative amount or time-bounded allowance. - The commands to which the policy applies. - Clear user-facing disclosure when the policy is enabled. 4. Treat server-provided quote fields only as pricing and eligibility information. They must not establish consent. 5. Revalidate the final price immediately before submission and reject the operation if it exceeds the locally approved amount. 6. Align documentation and implementation. If explicit confirmation is guaranteed, enforce it uniformly in every paid command. 7. Reduce the watch-only Skill’s attack surface by shipping a dedicated CLI exposing only `watch list`, `create`, `pause`, `resume`, `delete`, `digest`, and `events`, or enforce a strict watch-command allowlist in this Skill package. 8. Add regression tests proving that `analyze` and `voc` cannot submit paid requests without `--confirm`, even when a mocked quote response includes `autoConfirm: true`, sufficient balance, and an arbitrarily high `autoConfirmMaxCredits`.
