9. 安全与最佳实践
代币相关的安全问题可能导致资金损失。本章总结常见风险和防范措施。
9.1 常见安全漏洞
1. 权限未正确管理
问题:Mint Authority 或 Freeze Authority 泄露或未及时移除。
rust// 错误示例:硬编码权限地址 pub const ADMIN: Pubkey = pubkey!("Admin1111..."); // 正确做法:使用 PDA 或可配置的权限 #[account( constraint = authority.key() == config.admin @ ErrorCode::Unauthorized )] pub authority: Signer<'info>,
2. 缺少账户校验 (Mint Mismatch)
问题:未验证传入账户的合法性,导致攻击者可以传入恶意账户。例如,你的程序本意是接收 USDC,但攻击者传入了一个由他控制的垃圾代币账户。
rust// 错误示例:未验证 mint pub struct BadTransfer<'info> { pub mint: Account<'info, Mint>, // 任意 mint 都能传入 #[account(mut)] pub from: Account<'info, TokenAccount>, // ... } // 正确做法:验证 Token Account 的 mint pub struct SafeTransfer<'info> { pub mint: Account<'info, Mint>, #[account( mut, constraint = from.mint == mint.key() @ ErrorCode::MintMismatch )] pub from: Account<'info, TokenAccount>, // ... }
3. 未检查签名 (Missing Signer)
问题:关键操作未要求正确的签名者。如果 authority 只是 AccountInfo 而不是 Signer,任何人都可以传入别人的公钥来操作别人的账户。
rust// 正确做法:明确要求签名 #[account( mut, constraint = token_account.owner == authority.key() )] pub token_account: Account<'info, TokenAccount>, #[account(mut)] pub authority: Signer<'info>, // 必须是 Signer
9.2 Token Account 安全
1. 验证 Token Account 所有权
始终验证 Token Account 属于预期的所有者:
rust#[account( mut, token::mint = expected_mint, token::authority = expected_owner, )] pub token_account: Account<'info, TokenAccount>,
2. 防止 ATA 欺诈
攻击者可能创建非 ATA 的 Token Account 并尝试混淆。对于大多数用户场景,强制使用 ATA 是更安全的。
rust// 强制使用 ATA #[account( associated_token::mint = mint, associated_token::authority = owner, )] pub token_account: Account<'info, TokenAccount>,