T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:205
- Finding
- Remote API Calldata Is Submitted for Signing Without Mandatory Independent Verification<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:205-214`; related behavior in `references/privy.md:7-10` **Vulnerability Type**: `T09: Insecure Skill Coding Practices` **Risk Level**: High ### Vulnerable Code `SKILL.md:205-214`: ```markdown **If `onchain-verify-transaction` is not installed**, apply these best-effort checks instead and be transparent about the reduced safety: 1. Tell the user: `"The onchain-verify-transaction skill is not installed. Calldata verification is unavailable — install it for stronger execution safety (clawhub install onchain-verify-transaction)."` 2. Decode the spender address and approval amount from `steps[0].params.data`. The approval amount must be exactly equal to the swap input amount — no more. If the calldata encodes an unlimited approval or any amount materially larger than the input, stop, warn the user explicitly, and require confirmation before sending. 3. Otherwise proceed with execution — the user's swap intent is confirmed, do not add further confirmation prompts. ### 4. Send transactions in order Pass each `steps[].params` to Privy's `eth_sendTransaction` RPC method in order. Send one at a time and wait for confirmation before the next. ``` `references/privy.md:7-10`: ```markdown When passing `steps[].params` to Privy's `eth_sendTransaction`: - **`value` must be a hex string** — e.g. `"0x0"`, not `0` or `"0"`. Privy will reject non-hex values. - All other fields (`from`, `to`, `data`) pass through as-is from the spanDEX response. ``` ### Technical Analysis The Skill obtains executable EVM transaction fields from the remotely configured spanDEX endpoint and passes those fields to Privy's signing RPC. Independent transaction simulation is optional rather than mandatory. When the verification Skill is absent, the documented fallback only decodes the spender and approval amount from the first transaction. It does not comprehensively enforce: - The permitted transaction destination and contract ...[truncated 2662 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Make independent simulation and asset-flow verification mandatory for execution. If trusted verification is unavailable, restrict the Skill to quote-only and dry-run modes. 2. Locally decode and validate every transaction before requesting a signature. 3. Enforce an explicit schema and reject unknown, duplicate, reordered, or additional steps. 4. Require every `from` field to equal the selected Privy-managed wallet. 5. Validate the chain ID, destination contract, function selector, input token, output token, recipient, approval spender, approval amount, and native-token value against the confirmed swap intent. 6. Require the approval amount to equal the required input amount and reject unlimited or materially larger approvals without exception. 7. Simulate the complete transaction sequence against current chain state and verify maximum input loss, minimum output, recipient balances, allowance changes, and native-asset flows. 8. Maintain reviewed router and spender allowlists, ideally tied to verified contract bytecode rather than addresses alone. 9. Display decoded effects and require explicit user confirmation when verification cannot establish all expected asset flows. 10. Apply restrictive Privy wallet policies, including destination allowlists, per-token spending limits, native-value limits, and transaction-rate limits. ]]>
