T09 · Insecure Skill Coding Practices
Error
- Location
- references/evm-to-evm.md:118
- Finding
- Financial transfer handlers omit mandatory confirmation and comprehensive input validation<![CDATA[ ## Vulnerability Details **File Locations**: - `references/deposit-evm.md:87-106` - `references/deposit-solana.md:66-80` - `references/evm-to-evm.md:118-164` - `references/evm-to-solana.md:187-289` - `references/solana-to-evm.md:245-294` - `references/solana-to-solana.md:291-371` - `references/transfer-evm-circle-wallet.md:179-214` **Vulnerability Type**: Missing transaction confirmation and insufficient validation of financial-operation parameters **Risk Level**: High ### Vulnerable Code A representative vulnerable transfer path appears in `references/evm-to-evm.md`: ```tsx const handleTransfer = async (input: EvmBurnIntentInput, network: NetworkType = "testnet") => { if (!evmAddress) return; const sourceChain = input.sourceChainConfig[network]; const destChain = input.destinationChainConfig[network]; if (!sourceChain || !destChain) return; try { setError(null); setStep("signing"); const recipient = (input.recipientAddress ?? evmAddress) as Hex; const transferAmount = parseUnits(input.transferAmountUsdc, 6); const burnIntent = { maxBlockHeight: maxUint64.toString(), maxFee: MAX_FEE.toString(), spec: { version: 1, sourceDomain: input.sourceChainConfig.domain, destinationDomain: input.destinationChainConfig.domain, sourceContract: evmAddressToBytes32(sourceChain.GatewayWallet as Hex), destinationContract: evmAddressToBytes32(destChain.GatewayMinter as Hex), sourceToken: evmAddressToBytes32(sourceChain.USDCAddress as Hex), destinationToken: evmAddressToBytes32(destChain.USDCAddress as Hex), sourceDepositor: evmAddressToBytes32(evmAddress), destinationRecipient: evmAddressToBytes32(recipient), sourceSigner: evmAddressToBytes32(evmAddress), destinationCaller: evmAddressToBytes32(zeroAddress), value: transferAmount.toString(), salt: randomHex32(), hookData: "0x" as Hex, }, }; cons ...[truncated 3684 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Introduce a mandatory confirmation state before any wallet signature, token approval, deposit, burn-intent submission, or mint transaction. 2. Display a trusted summary containing: - Token symbol and verified token contract or mint - Human-readable amount and base-unit amount - Maximum fee - Source network and domain - Destination network and domain - Source account - Final recipient account - Gateway Wallet and Gateway Minter addresses 3. Require a fresh, explicit confirmation after the summary is generated. Do not treat clicking an earlier navigation or form button as transfer confirmation. 4. Validate amounts with strict decimal syntax and reject zero, negative, excessive-precision, overflowed, or policy-exceeding values. 5. Validate EVM addresses with a canonical address validator and Solana addresses with `PublicKey`. For Solana recipients, verify whether the input is already a USDC token account before deriving an associated token account. 6. Resolve domain IDs, token addresses, and Gateway contracts exclusively from an allowlisted network configuration. Verify that all selected values belong to the same intended environment. 7. Require a separate mainnet acknowledgment and display a prominent warning for mainnet or transfers above the configured safety threshold. 8. Revalidate all values immediately before signing to prevent time-of-check/time-of-use changes in application state. 9. For developer-controlled wallets, require an authenticated approval workflow, transaction policy limits, destination allowlists where appropriate, and audit logging that excludes secrets and sensitive signing material. ]]>
