T09 · Insecure Skill Coding Practices
- Location
skill.md:72- Finding
Blind Signing of an Unverified Server-Generated Solana Transaction
- Content
View full analysis
Vulnerability Details
File Location:
skill.md, lines 72-110
Vulnerability Type: Blind signing of an untrusted blockchain transaction
Risk Level: HighVulnerable Code
json { "transaction": "<base64_encoded_transaction>", "nftMint": "<public_key_of_new_nft>", "villainId": 42, "imageUrl": "https://...", "traits": {"body_color": "green", "hat": "top_hat", ...}, "rarityScore": 73 }markdown The `transaction` is a base64-encoded, partially-signed Solana transaction. The backend has co-signed it as collection authority.javascript import { VersionedTransaction } from "@solana/web3.js"; const tx = VersionedTransaction.deserialize( Buffer.from(transaction, "base64") ); tx.sign([yourKeypair]);javascript const signedTxBase64 = Buffer.from(tx.serialize()).toString("base64");bash curl -X POST https://chum-production.up.railway.app/api/villain/execute \ -H "Content-Type: application/json" \ -d '{ "transaction": "<base64_encoded_signed_transaction>" }'Technical Analysis
The skill directs the user to retrieve an opaque, partially signed transaction from a remote backend, deserialize it, and sign it with a funded Solana wallet. It does not require validation of the transaction message before signing.
Local signing protects the private key from direct disclosure, but it does not protect the assets controlled by that key. A valid signature authorizes the instructions encoded in the transaction. The documented flow does not verify:
- The invoked Solana program IDs.
- The transaction fee payer.
- Writable and signer accounts.
- SOL transfer recipients and amounts.
- Token or NFT transfers.
- Authority changes, approvals, or delegations.
- The expected mint and collection addresses.
- The claimed
0.001 SOLmint price or a maximum total debit. - Address lookup tables used by a v ...[truncated 1735 chars]
- Remediation
View remediation
Remediation Suggestions
- Decode and validate the complete transaction message before requesting a signature.
- Allow only explicitly expected program IDs, including the precise Metaplex and System Program operations required for minting.
- Verify every account referenced by every instruction, including signer and writable flags.
- Confirm the fee payer, expected NFT mint, collection address, destination wallet, and collection authority against trusted local configuration rather than backend response fields.
- Calculate all SOL and token balance changes and reject transactions exceeding the advertised mint price and a conservative maximum network-fee threshold.
- Reject token transfers, NFT transfers, delegate approvals, authority changes, durable nonces, unexpected compute-budget settings, and unknown instructions unless they are explicitly required and documented.
- For versioned transactions, resolve and validate all address lookup tables before signing; reject unknown or mutable lookup-table dependencies.
- Present a human-readable transaction summary—including recipients, amounts, programs, assets, and authority changes—and require explicit confirmation.
- Compare
nftMintand the collection address with the addresses encoded in the actual transaction rather than trusting separate JSON metadata. - Submit the validated signed transaction directly to a trusted Solana RPC endpoint where practical, reducing reliance on the transaction-producing backend.
- Use a dedicated wallet containing only the minimum funds necessary for the mint to limit loss if validation fails.
