solana-security
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSolana Security Auditing
Solana安全审计
Systematic security review framework for Solana programs, supporting both Anchor and native Rust implementations.
针对Solana程序的系统化安全审查框架,支持Anchor和原生Rust两种实现方式。
Review Process
审查流程
Follow this systematic 5-step process for comprehensive security audits:
遵循以下系统化的5步流程,完成全面的安全审计:
Step 1: Initial Assessment
步骤1:初始评估
Understand the program's context and structure:
- Framework: Anchor vs Native Rust (check for )
use anchor_lang::prelude::* - Anchor version: Check for compatibility and known issues
Cargo.toml - Dependencies: Oracles (Pyth, Switchboard), external programs, token programs
- Program structure: Count instructions, identify account types, analyze state management
- Complexity: Lines of code, instruction count, PDA patterns
- Purpose: DeFi, NFT, governance, gaming, etc.
了解程序的背景和结构:
- 框架类型:Anchor或原生Rust(检查是否使用)
use anchor_lang::prelude::* - Anchor版本:查看确认兼容性及已知问题
Cargo.toml - 依赖项:预言机(Pyth、Switchboard)、外部程序、代币程序
- 程序结构:统计指令数量、识别账户类型、分析状态管理方式
- 复杂度:代码行数、指令数量、PDA模式
- 用途:DeFi、NFT、治理、游戏等
Step 2: Systematic Security Review
步骤2:系统化安全审查
For each instruction, perform security checks in this order:
- Account Validation - Verify signer, owner, writable, and initialization checks
- Arithmetic Safety - Check all math operations use methods
checked_* - PDA Security - Validate canonical bumps and seed uniqueness
- CPI Security - Ensure cross-program invocations validate target programs
- Oracle/External Data - Verify price staleness and oracle status checks
→ See references/security-checklists.md for detailed checklists
针对每个指令,按以下顺序执行安全检查:
- 账户验证 - 验证签名者、所有者、可写性及初始化检查
- 算术安全性 - 检查所有数学运算是否使用方法
checked_* - PDA安全性 - 验证规范bump值及种子唯一性
- CPI安全性 - 确保跨程序调用验证目标程序
- 预言机/外部数据 - 验证价格时效性及预言机状态
→ 详情请查看references/security-checklists.md中的检查清单
Step 3: Vulnerability Pattern Detection
步骤3:漏洞模式检测
Scan for common vulnerability patterns:
- Type cosplay attacks
- Account reloading issues
- Improper account closing
- Missing lamports checks
- PDA substitution attacks
- Arbitrary CPI vulnerabilities
- Missing ownership validation
- Integer overflow/underflow
→ See references/vulnerability-patterns.md for code examples and exploit scenarios
扫描常见的漏洞模式:
- 类型冒充攻击
- 账户重载问题
- 不当账户关闭
- 缺失lamports检查
- PDA替换攻击
- 任意CPI漏洞
- 缺失所有权验证
- 整数溢出/下溢
→ 详情请查看references/vulnerability-patterns.md中的代码示例和利用场景
Step 4: Architecture and Testing Review
步骤4:架构与测试审查
Evaluate overall design quality:
- PDA design patterns and collision prevention
- Account space allocation and rent exemption
- Error handling approach and coverage
- Event emission for critical state changes
- Compute budget optimization
- Test coverage (unit, integration, fuzz)
- Upgrade strategy and authority management
评估整体设计质量:
- PDA设计模式及冲突预防
- 账户空间分配及租金豁免
- 错误处理方式及覆盖范围
- 关键状态变更的事件发射
- 计算预算优化
- 测试覆盖率(单元测试、集成测试、模糊测试)
- 升级策略及权限管理
Step 5: Generate Security Report
步骤5:生成安全报告
Provide findings using this structure:
Severity Levels:
- 🔴 Critical: Funds can be stolen/lost, protocol completely broken
- 🟠 High: Protocol can be disrupted, partial fund loss possible
- 🟡 Medium: Suboptimal behavior, edge cases, griefing attacks
- 🔵 Low: Code quality, gas optimization, best practices
- 💡 Informational: Recommendations, improvements, documentation
Finding Format:
markdown
undefined按照以下结构呈现审计结果:
严重等级:
- 🔴 严重:资金可能被盗/丢失,协议完全失效
- 🟠 高风险:协议可能被破坏,存在部分资金损失风险
- 🟡 中风险:行为不符合最优标准,存在边缘情况、恶意干扰攻击风险
- 🔵 低风险:代码质量、gas优化、最佳实践问题
- 💡 信息性:优化建议、改进方案、文档完善
审计结果格式:
markdown
undefined🔴 [CRITICAL] Title
🔴 [严重] 标题
Location:
programs/vault/src/lib.rs:45-52Issue:
Brief description of the vulnerability
Vulnerable Code:
rust
// Show the problematic codeExploit Scenario:
Step-by-step explanation of how this can be exploited
Recommendation:
rust
// Show the secure alternativeReferences:
- [Link to relevant documentation or similar exploits]
**Report Summary:**
- Total findings by severity
- Critical issues first (prioritize by risk)
- Quick wins (easy fixes with high impact)
- Recommendations for testing improvements位置:
programs/vault/src/lib.rs:45-52问题描述:
漏洞的简要说明
漏洞代码:
rust
// 展示有问题的代码利用场景:
漏洞被利用的分步说明
修复建议:
rust
// 展示安全的替代代码参考资料:
- [相关文档或类似漏洞的链接]
**报告摘要:**
- 各严重等级的问题总数
- 优先展示严重问题(按风险排序)
- 快速修复项(易实施且影响大的修复)
- 测试改进建议Quick Reference
快速参考
Essential Checks (Every Instruction)
核心检查项(每个指令都需执行)
Anchor:
rust
// ✅ Account validation with constraints
#[derive(Accounts)]
pub struct SecureInstruction<'info> {
#[account(
mut,
has_one = authority, // Relationship check
seeds = [b"vault", user.key().as_ref()],
bump, // Canonical bump
)]
pub vault: Account<'info, Vault>,
pub authority: Signer<'info>, // Signer required
pub token_program: Program<'info, Token>, // Program validation
}
// ✅ Checked arithmetic
let total = balance.checked_add(amount)
.ok_or(ErrorCode::Overflow)?;Native Rust:
rust
// ✅ Manual account validation
if !authority.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
if vault.owner != program_id {
return Err(ProgramError::IllegalOwner);
}
// ✅ Checked arithmetic
let total = balance.checked_add(amount)
.ok_or(ProgramError::ArithmeticOverflow)?;Anchor:
rust
// ✅ 带约束的账户验证
#[derive(Accounts)]
pub struct SecureInstruction<'info> {
#[account(
mut,
has_one = authority, // 关系检查
seeds = [b"vault", user.key().as_ref()],
bump, // 规范bump值
)]
pub vault: Account<'info, Vault>,
pub authority: Signer<'info>, // 需要签名者
pub token_program: Program<'info, Token>, // 程序验证
}
// ✅ 安全算术运算
let total = balance.checked_add(amount)
.ok_or(ErrorCode::Overflow)?;原生Rust:
rust
// ✅ 手动账户验证
if !authority.is_signer {
return Err(ProgramError::MissingRequiredSignature);
}
if vault.owner != program_id {
return Err(ProgramError::IllegalOwner);
}
// ✅ 安全算术运算
let total = balance.checked_add(amount)
.ok_or(ProgramError::ArithmeticOverflow)?;Critical Anti-Patterns
关键反模式
❌ Never Do:
- Use arithmetic methods (hide errors)
saturating_* - Use or
unwrap()in production codeexpect() - Use without additional checks
init_if_needed - Skip signer validation ("they wouldn't call this...")
- Use unchecked arithmetic operations
- Allow arbitrary CPI targets
- Forget to reload accounts after mutations
✅ Always Do:
- Use arithmetic (
checked_*,checked_add, etc.)checked_sub - Use for Option unwrapping
ok_or(error)? - Use explicit with proper validation
init - Require or
Signer<'info>checksis_signer - Use for CPI program validation
Program<'info, T> - Reload accounts after external calls that mutate state
- Validate account ownership, discriminators, and relationships
❌ 绝对禁止:
- 使用算术方法(会隐藏错误)
saturating_* - 在生产代码中使用或
unwrap()expect() - 未添加额外检查就使用
init_if_needed - 跳过签名者验证(“他们不会调用这个...”)
- 使用未检查的算术运算
- 允许任意CPI目标
- 状态变更后忘记重载账户
✅ 必须执行:
- 使用算术方法(
checked_*、checked_add等)checked_sub - 使用处理Option解包
ok_or(error)? - 使用显式并配合适当验证
init - 要求或
Signer<'info>检查is_signer - 对CPI程序目标使用验证
Program<'info, T> - 外部调用导致状态变更后重载账户
- 验证账户所有权、鉴别器及关系
Framework-Specific Patterns
框架特定模式
Anchor Security Patterns
Anchor安全模式
→ See references/anchor-security.md for:
- Account constraint best practices
- Common Anchor-specific vulnerabilities
- Secure CPI patterns with
CpiContext - Event emission and monitoring
- Custom error handling
→ 详情请查看references/anchor-security.md:
- 账户约束最佳实践
- Anchor特有的常见漏洞
- 使用的安全CPI模式
CpiContext - 事件发射与监控
- 自定义错误处理
Native Rust Security Patterns
原生Rust安全模式
→ See references/native-security.md for:
- Manual account validation patterns
- Secure PDA derivation and signing
- Low-level CPI security
- Account discriminator patterns
- Rent exemption validation
→ 详情请查看references/native-security.md:
- 手动账户验证模式
- 安全的PDA派生与签名
- 底层CPI安全
- 账户鉴别器模式
- 租金豁免验证
Modern Practices (2025)
2025年最佳实践
- Use Anchor 0.30+ for latest security features
- Implement Token-2022 with proper extension handling
- Use derive for automatic space calculation
InitSpace - Emit events for all critical state changes
- Write fuzz tests with Trident framework
- Document invariants in code comments
- Follow progressive roadmap: Dev → Audit → Testnet → Audit → Mainnet
- 使用Anchor 0.30+版本以获取最新安全特性
- 集成Token-2022并正确处理扩展
- 使用派生宏自动计算空间
InitSpace - 为所有关键状态变更发射事件
- 使用Trident框架编写模糊测试
- 在代码注释中记录不变量
- 遵循渐进式上线流程:开发 → 审计 → 测试网 → 再审计 → 主网
Security Fundamentals
安全基础
→ See references/security-fundamentals.md for:
- Security mindset and threat modeling
- Core validation patterns (signers, owners, mutability)
- Input validation best practices
- State management security
- Arithmetic safety
- Re-entrancy considerations
→ 详情请查看references/security-fundamentals.md:
- 安全思维与威胁建模
- 核心验证模式(签名者、所有者、可变性)
- 输入验证最佳实践
- 状态管理安全
- 算术安全性
- 重入考虑
Common Vulnerabilities
常见漏洞
→ See references/vulnerability-patterns.md for:
- Missing signer validation
- Integer overflow/underflow
- PDA substitution attacks
- Account confusion
- Arbitrary CPI
- Type cosplay
- Improper account closing
- Precision loss in calculations
Each vulnerability includes:
- ❌ Vulnerable code example
- 💥 Exploit scenario
- ✅ Secure alternative
- 📚 References
→ 详情请查看references/vulnerability-patterns.md:
- 缺失签名者验证
- 整数溢出/下溢
- PDA替换攻击
- 账户混淆
- 任意CPI
- 类型冒充
- 不当账户关闭
- 计算精度损失
每个漏洞包含:
- ❌ 漏洞代码示例
- 💥 利用场景
- ✅ 安全替代方案
- 📚 参考资料
Security Checklists
安全检查清单
→ See references/security-checklists.md for:
- Account validation checklist
- Arithmetic safety checklist
- PDA and account security checklist
- CPI security checklist
- Oracle and external data checklist
- Token integration checklist
→ 详情请查看references/security-checklists.md:
- 账户验证清单
- 算术安全清单
- PDA与账户安全清单
- CPI安全清单
- 预言机与外部数据清单
- 代币集成清单
Known Issues and Caveats
已知问题与注意事项
→ See references/caveats.md for:
- Solana-specific quirks and gotchas
- Anchor framework limitations
- Testing blind spots
- Common misconceptions
- Version-specific issues
→ 详情请查看references/caveats.md:
- Solana特有的特性与陷阱
- Anchor框架限制
- 测试盲区
- 常见误解
- 版本特定问题
Security Resources
安全资源
→ See references/resources.md for:
- Official security documentation
- Security courses and tutorials
- Vulnerability databases
- Audit report examples
- Security tools (Trident, fuzzers)
- Security firms and auditors
→ 详情请查看references/resources.md:
- 官方安全文档
- 安全课程与教程
- 漏洞数据库
- 审计报告示例
- 安全工具(Trident、模糊测试器)
- 安全公司与审计机构
Key Questions for Every Audit
每次审计的核心问题
Always verify these critical security properties:
-
Can an attacker substitute accounts?
- PDA validation, program ID checks, has_one constraints
-
Can arithmetic overflow or underflow?
- All math uses checked operations, division by zero protected
-
Are all accounts properly validated?
- Owner, signer, writable, initialized checks present
-
Can the program be drained?
- Authorization checks, reentrancy protection, account confusion prevention
-
What happens in edge cases?
- Zero amounts, max values, closed accounts, expired data
-
Are external dependencies safe?
- Oracle validation (staleness, status), CPI targets verified, token program checks
始终验证以下关键安全属性:
-
攻击者能否替换账户?
- PDA验证、程序ID检查、has_one约束
-
是否存在算术溢出或下溢风险?
- 所有运算使用安全方法,防止除零错误
-
所有账户是否都经过适当验证?
- 存在所有者、签名者、可写性、初始化检查
-
程序资金是否可能被耗尽?
- 授权检查、重入保护、账户混淆预防
-
边缘情况下会发生什么?
- 零金额、最大值、已关闭账户、过期数据
-
外部依赖是否安全?
- 预言机验证(时效性、状态)、CPI目标验证、代币程序检查
Audit Workflow
审计工作流
Before Starting
开始之前
- Understand the protocol purpose and mechanics
- Review documentation and specifications
- Set up local development environment
- Run existing tests and check coverage
- 理解协议的用途与机制
- 审查文档与规范
- 搭建本地开发环境
- 运行现有测试并检查覆盖率
During Audit
审计过程中
- Follow the 5-step review process systematically
- Document findings with severity and remediation
- Create proof-of-concept exploits for critical issues
- Test fixes and verify they work
- 系统化遵循5步审查流程
- 记录问题的严重等级与修复方案
- 为严重问题编写概念验证(PoC)利用代码
- 测试修复方案并验证有效性
After Audit
审计完成后
- Present findings clearly prioritized by severity
- Provide actionable remediation steps
- Re-audit after fixes are implemented
- Document lessons learned for the protocol
- 按严重等级优先顺序清晰呈现问题
- 提供可执行的修复步骤
- 修复完成后重新审计
- 记录针对该协议的经验教训
Testing for Security
安全测试
Beyond code review, validate security through testing:
- Unit tests: Test each instruction's edge cases
- Integration tests: Test cross-instruction interactions
- Fuzz testing: Use Trident to discover unexpected behaviors
- Exploit scenarios: Write POCs for found vulnerabilities
- Upgrade testing: Verify migration paths are secure
除代码审查外,通过测试验证安全性:
- 单元测试:测试每个指令的边缘情况
- 集成测试:测试跨指令交互
- 模糊测试:使用Trident发现意外行为
- 漏洞利用场景:为发现的漏洞编写PoC
- 升级测试:验证迁移路径的安全性
Core Principle
核心原则
In Solana's account model, attackers can pass arbitrary accounts to any instruction.
Security requires explicitly validating:
- ✅ Every account's ownership
- ✅ Every account's type (discriminator)
- ✅ Every account's relationships
- ✅ Every account's state
- ✅ Every signer requirement
- ✅ Every arithmetic operation
- ✅ Every external call
There are no implicit guarantees. Validate everything, trust nothing.
在Solana的账户模型中,攻击者可以向任意指令传入任意账户。
安全需要显式验证:
- ✅ 每个账户的所有权
- ✅ 每个账户的类型(鉴别器)
- ✅ 每个账户的关系
- ✅ 每个账户的状态
- ✅ 每个签名者要求
- ✅ 每个算术运算
- ✅ 每个外部调用
没有隐式保证。验证所有内容,不相信任何东西。