T09 Β· Insecure Skill Coding Practices
Error
- Location
- scripts/register-name.js:341
- Finding
- Unvalidated API Response Controls a Paid Blockchain Transaction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/register-name.js:341-348`, `scripts/register-name.js:413-427`, and `scripts/register-name.js:476-489` **Vulnerability Type**: Insufficient validation of externally supplied transaction parameters **Risk Level**: High ### Vulnerable Code ```javascript const result = await makeApiRequest('/api/register-request', 'POST', requestBody); if (!result.registerData || !result.signature || !result.price) { throw new Error('Invalid API response: missing required fields'); } console.log('β Got registration data from API'); console.log(`π° Price: ${result.price} ${paymentToken}`); return result; ``` ```javascript const apiResponse = await getRegistrationData( name, wallet.address, setPrimary, referrer ); const { registerData, signature, price } = apiResponse; let priceInWei; if (typeof price === 'string') { priceInWei = ethers.parseEther(price); } else if (typeof price === 'number') { priceInWei = ethers.parseEther(price.toString()); } else { throw new Error(`Invalid price format: ${price}`); } ``` ```javascript const contractInterface = new ethers.Interface([ 'function registerWithSignature(tuple(string name, address nameOwner, bool setAsPrimaryName, address referrer, bytes32 discountKey, bytes[] discountClaimProof, uint256 nonce, uint256 deadline, bytes attributes, address paymentToken) registerData, bytes signature) payable' ]); const data = contractInterface.encodeFunctionData( 'registerWithSignature', [registerData, signature] ); const tx = { to: NNS_CONTRACT, value: priceInWei, data: data, gasLimit: gasLimit, gasPrice: gasPrice }; const result = await signer.sendTransaction(tx); ``` ### Technical Analysis The remote NAD API supplies both the structured registration parameters and the price used in the transaction. The script only checks that `registerData`, `signature`, and `price` are present. It does not verify that the returned data matches the user's request. ...[truncated 2122 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Define and enforce a strict schema for the API response. 2. Validate that `registerData.name` exactly matches the normalized requested name. 3. Require `registerData.nameOwner` to equal the local wallet address. 4. Compare `setAsPrimaryName`, `referrer`, and `paymentToken` with locally constructed expected values. 5. Reject expired or excessively long deadlines and validate nonce semantics. 6. Enforce a user-configurable maximum price and reject negative, noncanonical, non-finite, or excessively precise values. 7. Decode the final calldata locally and display all effective transaction fields. 8. Require explicit interactive confirmation, such as typing the normalized name and final price, unless a separately documented noninteractive flag is supplied. 9. Prefer locally constructing all transaction fields that do not require server authorization. 10. Obtain the expected contract address and signing authority from authenticated, versioned configuration and verify the server signature locally where feasible. ]]>
