T09 · Insecure Skill Coding Practices
Warning
- Location
- src/adapter.ts:14
- Finding
- Billable GPU Rentals Bypass Documented Confirmation and Balance Safeguards## Vulnerability Details **File Location**: `src/adapter.ts:14-16` **Vulnerability Type**: Missing authorization and financial precondition enforcement **Risk Level**: Medium ### Vulnerable Code ```typescript case 'rent': // params: { id: number, image: string } return await client.rent(params.id, params.image); ``` The safeguards that should precede this operation appear only in `SKILL.md:10-17`: ```markdown - **Pre-flight Check**: Before renting, call `balance` to ensure the user has sufficient funds. - **Step 2**: Search for offers and present the top 3 cheapest options to the user. - **Step 3**: Upon confirmation, call `rent`. - **Reporting**: If credit is below $5.00, warn the user after every successful rental. ``` ### Technical Analysis The `rent` action creates a billable VAST.ai instance, but the adapter does not enforce the documented user-confirmation or balance-check requirements. It accepts an action and parameters from its caller and immediately invokes `client.rent()`. Security-sensitive and financially consequential controls cannot safely rely solely on natural-language agent instructions. A direct API caller, an incorrectly behaving agent, or manipulated upstream input can invoke the adapter without following `SKILL.md`. The implementation also does not reject malformed or unexpected rental identifiers and does not enforce a minimum balance or spending limit. ### Attack Path 1. An attacker or erroneous upstream agent gains the ability to invoke `VastSkill.execute()` with the victim's execution context. 2. The caller submits the `rent` action with an offer ID and optional image: ```typescript VastSkill.execute("rent", { id: 12345, image: "pytorch/pytorch" }, context) ``` 3. The adapter does not require proof of user confirmation. 4. The adapter does not call `getBalance()` or verify that sufficient credit is available. 5. `VastClient.rent()` issues a `PUT` request t ...[truncated 685 chars]
- Remediation
- ## Remediation Suggestions 1. Enforce confirmation in code rather than relying on agent instructions. Require a short-lived, server-generated confirmation token bound to the selected offer, image, price, account, and expiration time. 2. Query the current account balance immediately before creating the instance and reject the operation if the configured minimum balance or spending policy is not satisfied. 3. Obtain the authoritative offer price immediately before rental and enforce an explicit user-approved maximum hourly price. 4. Validate `params.id` as a positive safe integer and restrict image values to an approved allowlist or require explicit confirmation for custom images. 5. Add account-level controls such as maximum hourly burn, maximum concurrent instances, and per-operation spending limits. 6. Return the required low-credit warning from the implementation so it cannot be omitted by the calling agent. 7. Record a security audit event for each attempted and completed rental without recording the API key. 8. Add automated tests proving that rentals fail without confirmation, with expired or mismatched confirmation tokens, and when financial limits are exceeded.
