T09 · Insecure Skill Coding Practices
Error
- Location
- SKILL.md:219
- Finding
- Unverified Server-Generated Solana Transaction Is Signed by the User Wallet## Vulnerability Details **File Location**: `SKILL.md:54-62, 201-221`; duplicated in `SKILL.txt:49-57, 196-216` **Vulnerability Type**: Blind signing of an externally generated blockchain transaction **Risk Level**: High ### Vulnerable Code Snippet From `SKILL.md:54-62`: ```markdown **Important:** The returned transaction must be signed by (1) the **mint keypair** (the keypair whose public key is `mint`) and (2) the **user wallet keypair** (the keypair for `userWallet`) before sending. Both signers are required. --- ### Send Transaction | Endpoint | Method | Request | Response | |----------|--------|---------|----------| | `/api/send-transaction` | POST | JSON: `{ signedTransaction }` – base64-encoded serialized **signed** Solana Transaction. | `{ success: true, signature }` – Solana transaction signature. | ``` From `SKILL.md:201-221`: ```markdown 1. **Generate mint keypair.** Create a Solana Keypair for the new token mint (e.g. `Keypair.generate()`). Use `keypair.publicKey.toBase58()` as `mint`. Store the keypair; you will need it to sign the pool transaction later. 4. **Pool transaction.** POST `https://kogaion.fun/api/create-pool-transaction` with JSON: - `mint` (from step 1), - `tokenName`, `tokenSymbol` (same as in metadata), - `metadataUri` (from step 3), - `userWallet` (creator/payer wallet base58). - Save the returned `poolTx` (base64). 5. **Sign.** Deserialize the transaction from base64. Sign with (1) the mint keypair from step 1, (2) the user wallet keypair. Serialize the signed transaction to base64. 6. **Send.** POST `https://kogaion.fun/api/send-transaction` with JSON `{ signedTransaction: base64 }`. Save the returned `signature`. ``` The same workflow appears in `SKILL.txt:49-57` and `SKILL.txt:196-216`. ### Technical Analysis The Skill directs the agent to obtain an opaque, serialized Solana transaction from the external `kogaion.fun` service and sign it with th ...[truncated 2303 chars]
- Remediation
- ## Remediation Suggestions 1. Decode the returned transaction before requesting any signature. 2. Enforce a strict allowlist of expected Solana program IDs and instruction types. 3. Verify all account addresses, including payer, mint, pool, recipient, authority, and fee accounts. 4. Verify all transfer amounts, service fees, token quantities, and balance changes against explicit user-approved limits. 5. Reject transactions containing additional or reordered instructions that are not part of a documented transaction template. 6. Confirm that the transaction's mint, metadata, token name, symbol, payer, and creator wallet match the original request. 7. Present a human-readable transaction simulation and balance-change summary before signing. 8. Require explicit human confirmation for every financially significant signature. 9. Simulate the transaction through a trusted Solana RPC endpoint and reject simulation errors or unexplained account changes. 10. Prefer constructing the transaction locally from reviewed instructions rather than signing an opaque server-generated payload. 11. Use a dedicated, low-balance wallet with no unrelated assets or authorities when interacting with the service. 12. Apply the same corrections to the duplicate workflow in `SKILL.txt`.
