T09 · Insecure Skill Coding Practices
Error
- Location
- index.js:60
- Finding
- Unsafe and Non-Canonical Transaction Amount Parsing## Vulnerability Details **File Location**: `index.js`, lines 60-69 and 104-116 **Vulnerability Type**: Improper input validation and unsafe numeric conversion **Risk Level**: High ### Vulnerable Code ```javascript async function sendSOL(recipientAddress, lamports) { const recipient = new PublicKey(recipientAddress); const sender = keypair.publicKey; const transaction = new Transaction().add( SystemProgram.transfer({ fromPubkey: sender, toPubkey: recipient, lamports: parseInt(lamports), }) ); ``` ```javascript // Send tokens const signature = await transfer( connection, keypair, senderTokenAccount.address, recipientTokenAccount.address, keypair, parseInt(amount) // assumes amount is in smallest unit (lamports for USDC, etc) ); ``` ### Technical Analysis Both transaction functions convert payment amounts with `parseInt` without first validating that the complete input is a canonical positive integer. This conversion is permissive: an input such as `1000000abc` is interpreted as `1000000`, while decimal values are silently truncated. The code also converts amounts to JavaScript `number` values without enforcing the `Number.MAX_SAFE_INTEGER` boundary. Large integer strings can therefore lose precision before transaction construction. No explicit minimum, maximum, balance-based policy, per-transaction limit, or confirmation control is enforced. This issue affects both the command-line interface and the exported programmatic API. Any Agent workflow that supplies amounts derived from untrusted quotes, messages, or generated content may authorize a value different from the exact value supplied by the caller. ### Attack Path 1. An attacker or untrusted Agent response supplies a crafted payment amount to a workflow using this Skill. 2. The workflow passes the value to `sendSOL`, `sendSPLToken`, `send-sol`, or `send-token` without independent validat ...[truncated 777 chars]
- Remediation
- ## Remediation Suggestions - Accept amounts only as digit-only strings or `bigint` values. - Reject empty, signed, decimal, exponential, hexadecimal, trailing-character, zero, and negative values. - Avoid conversion to JavaScript `number` when the Solana API supports `bigint`. - If a number is unavoidable, require `Number.isSafeInteger(value)` and `value > 0`. - Define explicit per-transaction and daily transfer limits. - Verify that the requested amount and expected fees are within the wallet balance. - Require an independent recipient-and-amount approval step before signing high-value transactions. - Use a validation pattern such as: ```javascript function parsePositiveAmount(value) { const text = String(value); if (!/^[0-9]+$/.test(text)) { throw new TypeError('Amount must be a positive integer in smallest units'); } const amount = BigInt(text); if (amount <= 0n) { throw new RangeError('Amount must be greater than zero'); } return amount; } ```
