T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:389
- Finding
- Blind Signing and Broadcasting of Untrusted Server-Supplied Transactions<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 389-408; also demonstrated at lines 132-144 **Vulnerability Type**: Missing transaction validation before cryptographic signing **Risk Level**: High ### Vulnerable Code ```typescript async function signAndSend(txString: string) { const bytes = Uint8Array.from(Buffer.from(txString, "base64")); // Try versioned transaction first, then legacy try { const tx = VersionedTransaction.deserialize(bytes); tx.sign([keypair]); const sig = await connection.sendRawTransaction(tx.serialize()); await connection.confirmTransaction(sig, "confirmed"); return sig; } catch { const tx = Transaction.from(bytes); tx.partialSign(keypair); const sig = await connection.sendRawTransaction(tx.serialize()); await connection.confirmTransaction(sig, "confirmed"); return sig; } } ``` ### Technical Analysis The Skill accepts an encoded transaction returned by the remote Breeze API, deserializes it, signs it with the user's Solana keypair, and broadcasts it without verifying its contents. Successful deserialization is incorrectly treated as sufficient authorization. The code does not validate: - Invoked Solana program IDs - Transaction instructions - Source and destination accounts - Token mint addresses - Transfer amounts - Account ownership or authority changes - Delegate approvals - Compute-budget or fee settings - Unexpected additional instructions - Whether the returned transaction corresponds to the user's confirmed request The API endpoint may also be changed through `X402_API_URL`. Consequently, a compromised endpoint, malicious endpoint configuration, DNS or infrastructure compromise, or upstream server vulnerability could provide an arbitrary transaction for signing. The versioned-transaction branch catches every error, including signing or transmission errors, and then attempts to parse the same data as a legacy transaction. This broad fallback further obscures the actual failure ...[truncated 1620 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Decode and inspect every transaction instruction before signing. 2. Maintain strict allowlists for: - Permitted Solana program IDs - Expected strategy and token accounts - Token mint addresses - Transfer recipients - Instruction types 3. Verify that transaction amounts exactly match the user-confirmed amount, subject only to explicitly disclosed fees. 4. Reject transactions containing additional or unexpected instructions. 5. Verify account ownership, signer requirements, writable accounts, delegate changes, and authority changes. 6. Bind the returned transaction to the original request by checking the wallet, strategy ID, mint, amount, and operation type. 7. Simulate the transaction through a trusted RPC endpoint and inspect balance changes before signing. 8. Present a human-readable transaction summary and require explicit user confirmation before any deposit or withdrawal signature. 9. Restrict or remove arbitrary `X402_API_URL` overrides for signing workflows. If overrides are required, require separate confirmation and an allowlisted HTTPS origin. 10. Use a dedicated, low-value wallet with limited funds rather than a general-purpose wallet. 11. Catch deserialization errors separately from signing, sending, and confirmation errors; do not use a broad catch block to change transaction formats after unrelated failures. ]]>
