T09 · Insecure Skill Coding Practices
- Location
scripts/create-token.ts:117- Finding
Blind Signing and Broadcasting of an Untrusted Remote Solana Transaction
- Content
View full analysis
''); throw new Error(`API request failed: ${res.status} ${res.statusText}\n${text}`); } const json = await res.json() as { data: { transaction: string; signature: string; dbc_config: string; dbc_pool: string; base_mint: string; name: string; symbol: string; uri: string; royalty_party: string; }; common: Record; }; const { transaction: txBase58, dbc_config, dbc_pool, base_mint, uri } = json.data; if (!txBase58) { throw new Error('API returned empty transaction. Response: ' + JSON.stringify(json)); } console.error(` base_mint: ${base_mint}`); console.error(` dbc_config: ${dbc_config}`); console.error(` dbc_pool: ${dbc_pool}`); console.error(` uri: ${uri}`); // ── Step 2: Deserialize and sign transaction ────────────────────────── const txBytes = bs58.decode(txBase58); const tx = VersionedTransaction.deserialize(txBytes); tx.sign([keypair]); // ── Step 3: Send to Solana RPC ──────────────────────────────────────── console.error('Sending transaction ...'); const txHash = await connection.sendRawTransaction(tx.serialize(), { skipPreflight: false, maxRetries: 3, }); ``` ### Technical Analysis The external API controls the serialized Solana transaction that the application signs. After decoding and deserializing the response, the code immediately calls `tx.sign([keypair])` and broadcasts the signed transaction. No validation is performed on: - The transaction fee payer. - Program IDs invoked by the transaction. - Instruction types and encoded instruction data. - Writable and signer accounts. - SOL or token transfer recipients and amo ...[truncated 2235 chars]- Remediation
View remediation
