CYBWithFlourish/vulnerable.so
GitHub: CYBWithFlourish/vulnerable.so
一个通过漏洞与修复代码对照的方式教授 Solana 智能合约安全的实践教学项目。
Stars: 2 | Forks: 1
# Solana 安全参考:教育性漏洞示例
[](https://www.anchor-lang.com/)
[](https://solana.com/)
[](LICENSE)
[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/ci.yml)
[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/scheduled-audit.yml)
[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/docs.yml)
## 目录
- [概述](#overview)
- [漏洞类别](#vulnerability-categories)
- [仓库结构](#repository-structure)
- [安装说明](#setup-instructions)
- [测试指南](#testing-guide)
- [学习路径](#learning-path)
- [贡献指南](#contribution-guidelines)
- [资源](#resources)
## 概述
本仓库为在 Solana 上进行开发的开发者提供了一个**安全第一的教育性参考**。每个示例都将**易受攻击的实现**与**安全版本**配对,并附有详细的解释,包括:
- 漏洞**是什么**
- **为什么**它很危险
- 攻击是**如何**运作的
- 修复**如何**防止攻击
所有代码都被设计为**对初学者友好**且**技术上准确**,使其非常适合:
- 刚接触 Solana 安全的开发者
- 学习 Solana 特定漏洞的安全审计人员
- 建立安全最佳实践的团队
- 教育研讨会和培训项目
**⚠️ 重要提示:** 这些程序均不应部署到生产环境中。它们是故意设置漏洞的教学示例。
## 漏洞类别
本仓库涵盖了 Solana 程序中常见的 **5 种关键漏洞类别**:
### 1. 缺少账户校验
**风险等级:** 🔴 关键
程序接受原始的 `AccountInfo`,而没有校验其所有权、类型或预期的派生路径。攻击者可以替换任意账户以破坏状态或提升权限。
**关键问题:**
- 没有所有权验证
- 缺少 discriminator 检查
- 缺乏 PDA seed 验证
- 没有权限绑定
📖 [完整教程](examples/01-missing-account-validation/README.md) | 💻 [漏洞代码](examples/01-missing-account-validation/example1.rs) | ✅ [修复代码](examples/01-missing-account-validation/example1.fix.rs)
### 2. 不正确的权限检查
**风险等级:** 🔴 关键
程序要求签名者,但从不验证该签名者是否确实被授权执行该操作。任何钱包都可以修改关键的协议参数。
**关键问题:**
- 有身份验证但无授权验证
- 缺少 `has_one` 约束
- 没有管理员验证
- 无限制的参数更改
📖 [完整教程](examples/02-incorrect-authority-check/README.md) | 💻 [漏洞代码](examples/02-incorrect-authority-check/example2.rs) | ✅ [修复代码](examples/02-incorrect-authority-check/example2.fix.rs)
### 3. 不安全的算术运算
**风险等级:** 🟠 高危
程序使用标准的算术运算符(`-`、`+`、`*`)而没有进行溢出检查。在 release 模式下,溢出会静默回绕(wrapping),导致余额损坏或无限铸造。
**关键问题:**
- 整数溢出/下溢
- 在 release 模式下静默回绕
- 缺少边界验证
- 缺乏 checked math 方法
📖 [完整教程](examples/03-unsafe-arithmetic/README.md) | 💻 [漏洞代码](examples/03-unsafe-arithmetic/example3.rs) | ✅ [修复代码](examples/03-unsafe-arithmetic/example3.fix.rs)
### 4. CPI 重入
**风险等级:** 🟠 高危
程序在更新内部状态之前调用了外部程序 (CPI)。恶意外部程序可以重新进入并利用陈旧的状态来耗尽资金。
**关键问题:**
- 在外部调用后更新状态
- 缺少重入锁 (reentrancy guards)
- 违反 CEI 模式
- 缺乏锁/标志
📖 [完整教程](examples/04-cpi-reentrancy/README.md) | 💻 [漏洞代码](examples/04-cpi-reentrancy/example4.rs) | ✅ [修复代码](examples/04-cpi-reentrancy/example4.fix.rs)
### 5. 签名者权限提升
**风险等级:** 🔴 关键
程序验证了一个账户是否为签名者,但并未验证该签名者的身份是否与存储在程序状态中的授权角色相匹配。任何签名者都可以提升权限。
**关键问题:**
- 只有 signer 类型而无身份检查
- 缺少 `has_one` 绑定
- 权限验证漏洞
- 基于角色的访问控制失败
📖 [完整教程](examples/05-signer-privilege-escalation/README.md) | 💻 [漏洞代码](examples/05-signer-privilege-escalation/example5.rs) | ✅ [修复代码](examples/05-signer-privilege-escalation/example5.fix.rs)
## 仓库结构
```
vulnerable.so/
├── README.md # This file
├── SECURITY.md # Comprehensive security documentation
├── Anchor.toml # Anchor workspace configuration
├── Cargo.toml # Rust workspace configuration
│
├── docs/
│ └── PINOCCHIO.md # Pinocchio testing guide
│
├── examples/ # Side-by-side vulnerable vs. fixed code
│ ├── 01-missing-account-validation/
│ │ ├── README.md # Full tutorial
│ │ ├── example1.rs # Vulnerable version
│ │ └── example1.fix.rs # Fixed version
│ ├── 02-incorrect-authority-check/
│ ├── 03-unsafe-arithmetic/
│ ├── 04-cpi-reentrancy/
│ └── 05-signer-privilege-escalation/
│
├── programs/ # Full Anchor programs (deployable)
│ ├── 01a-missing-account-validation-vuln/
│ ├── 01b-missing-account-validation-fix/
│ ├── 01c-missing-account-validation-attacker/
│ ├── 02a-incorrect-authority-vuln/
│ ├── 02b-incorrect-authority-fix/
│ ├── 02c-incorrect-authority-attacker/
│ ├── 03a-unsafe-arithmetic-vuln/
│ ├── 03b-unsafe-arithmetic-fix/
│ ├── 03c-unsafe-arithmetic-attacker/
│ ├── 04a-cpi-reentrancy-vuln/
│ ├── 04b-cpi-reentrancy-fix/
│ ├── 04c-cpi-reentrancy-attacker/
│ ├── 05a-signer-privilege-escalation-vuln/
│ ├── 05b-signer-privilege-escalation-fix/
│ └── 05c-signer-privilege-escalation-attacker/
│
└── scripts/
├── attacks/ # TypeScript attack demonstrations
│ ├── 01-missing-account-attack.ts
│ ├── 02-incorrect-authority-attack.ts
│ ├── 03-unsafe-arithmetic-attack.ts
│ └── 05-signer-privilege-attack.ts
└── cpi-reentrancy.ts # CPI reentrancy test
```
## 安装说明
### 前置条件
- **Rust** 1.75+ 及 `cargo`([安装 Rust](https://rustup.rs/))
- **Solana CLI** 1.18+([安装 Solana](https://docs.solana.com/cli/install-solana-cli-tools))
- **Anchor** 0.32.1([安装 Anchor](https://www.anchor-lang.com/docs/installation))
- **Node.js** 18+ 和 **Yarn**(用于 TypeScript 测试)
- **Pinocchio**(可选,用于快速测试)([安装 Pinocchio](https://github.com/anza-xyz/pinocchio))
### 安装
1. **克隆仓库:**
```
git clone https://github.com/CYBWithFlourish/vulnerable.so.git
cd vulnerable.so
```
2. **构建所有程序:**
```
anchor build
```
这将编译所有 15 个程序(5 个漏洞 × 每个包含 3 个版本)。
3. **安装 TypeScript 依赖:**
```
yarn install
```
4. **验证构建产物:**
```
ls -l target/deploy/*.so
ls -l target/idl/*.json
```
### Anchor 配置
本项目使用 Anchor 的工作区特性来管理多个程序。`Anchor.toml` 中的关键配置:
```
[programs.devnet]
cpi-reentrancy-vuln = "4tZXygwa8iqkS7AGGcqWptSzT8PGgQRYM3dAXCuF1rKB"
cpi-reentrancy-fix = "H8sBVtiyV2ZqWsfpZq2R7oKkyN1UQg61ddpxXsD5ouAQ"
cpi-reentrancy-attacker = "2SuAQ3vLxMomnMZP7bAHaHJXU5iyMDyxB2K5TbUnFZWH"
```
程序定义在工作区的 `Cargo.toml` 中,并共享依赖项:
- `anchor-lang = "0.32.1"`
- `pinocchio = "1.52"`
### Pinocchio 设置
Pinocchio 是一个快速、轻量级的 Solana 测试库,作为工作区依赖项包含在内。
1. **添加到您程序的 `Cargo.toml` 中:**
```
[dependencies]
pinocchio = { workspace = true }
```
2. **使用 Pinocchio 编写测试:**
```
#[cfg(test)]
mod tests {
use pinocchio::*;
#[test]
fn test_my_instruction() {
// Your test code
}
}
```
3. **运行测试:**
```
cargo test
```
📖 查看 [docs/PINOCCHIO.md](docs/PINOCCHIO.md) 获取完整的指南和示例。
## 测试指南
### 方法 1:Anchor 测试(完整验证节点)
使用本地验证节点运行完整的测试套件:
```
# 在后台启动本地 validator
solana-test-validator &
# 运行所有测试
anchor test
# 运行特定测试文件
anchor test -- --grep "CPI Reentrancy"
```
**优点:** 完整的 Solana 环境,逼真的模拟
**缺点:** 启动缓慢(约 30 秒),资源消耗大
### 方法 2:Pinocchio 库测试(快速模拟)
使用 Pinocchio 作为库依赖项测试单个程序:
```
# 运行所有 Pinocchio 测试
cargo test
# 运行特定 program 的测试
cargo test --package missing-account-validation-fix
# 带输出运行
cargo test -- --nocapture
```
**Pinocchio 测试示例:**
```
#[cfg(test)]
mod tests {
use pinocchio::pubkey::Pubkey;
#[test]
fn test_account_validation() {
let account = Pubkey::new_unique();
// Test your validation logic
println!("Testing with account: {}", account);
}
}
```
**优点:** 即时启动,轻量级,迭代快,集成在 `cargo test` 中
**缺点:** 运行时功能受限,简化了的环境
📖 查看 [docs/PINOCCHIO.md](docs/PINOCCHIO.md) 获取详细示例以及 `examples/*/example*.pinocchio.rs` 文件。
### 方法 3:攻击脚本
运行攻击演示脚本:
```
# Missing account substitution attack
ts-node scripts/attacks/01-missing-account-attack.ts
# Incorrect authority attack
ts-node scripts/attacks/02-incorrect-authority-attack.ts
# Unsafe arithmetic underflow attack
ts-node scripts/attacks/03-unsafe-arithmetic-attack.ts
# Signer privilege escalation attack
ts-node scripts/attacks/05-signer-privilege-attack.ts
```
每个脚本演示了:
1. 如何构造恶意交易
2. 为什么易受攻击的版本会接受它
3. 攻击是如何成功的
4. 为什么修复后的版本会拒绝它
## CI/CD 与自动化测试
本仓库包含全面的 GitHub Actions 工作流,用于持续集成和安全测试。
### 自动化工作流
#### 1. 安全测试 CI (`.github/workflows/ci.yml`)
在每次 push 和 pull request 时运行,以验证所有安全演示。
**任务:**
- **Build Programs**:编译所有 15 个 Solana 程序(5 个漏洞 × 3 个版本)
- **Attack Demonstrations**:运行针对漏洞 01、02、03 和 05 的 TypeScript 攻击脚本
- **Rust Unit Tests**:对所有程序变体执行 `cargo test-sbf`
- **Pinocchio Tests**:快速模拟测试
- **Security Summary**:汇总结果并发表 PR 评论
**状态**:[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/ci.yml)
#### 2. 每周安全审计 (`.github/workflows/scheduled-audit.yml`)
每周日 UTC 午夜运行,以确保持续的安全。
**任务:**
- **Dependency Audit**:使用 `cargo audit` 和 `npm audit` 检查漏洞
- **Version Compatibility**:针对最新的 Solana/Anchor 版本进行兼容性测试
- **Comprehensive Tests**:执行完整的测试套件
- **Issue Creation**:在失败时自动创建 GitHub issue
**状态**:[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/scheduled-audit.yml)
#### 3. 文档验证 (`.github/workflows/docs.yml`)
在修改 Markdown 文件时运行。
**任务:**
- **Markdown Linting**:验证 Markdown 语法和样式
- **Link Checking**:确保所有链接有效
- **Completeness Verification**:确认所有 5 个漏洞均已记录在案
- **Structure Validation**:检查必需的部分是否存在
**状态**:[](https://github.com/CYBWithFlourish/vulnerable.so/actions/workflows/docs.yml)
### 在本地运行测试
在提交修改之前,请在本地运行测试以便及早发现问题:
```
# 构建所有 programs
anchor build
# 运行特定 program 的 Rust 单元测试
cd programs/01a-missing-account-validation-vuln
cargo test-sbf
# 运行所有 Rust 测试(需要 Solana test validator)
cargo test-sbf --all
# 运行 attack 演示
yarn attack:01
yarn attack:02
yarn attack:03
yarn attack:05
# 或者使用 ts-node 手动运行
ts-node scripts/attacks/01-missing-account-attack.ts
```
### 理解 CI 结果
CI 系统提供清晰且具有教育意义的输出:
```
✅ Build Programs: SUCCESS
└─ Compiled 15 programs
⚠️ Attack Demo #01 (Missing Account): EXPECTED BEHAVIOR
└─ Vulnerable: Attack succeeded ✓
└─ Fixed: Attack blocked ✓
⚠️ Attack Demo #02 (Incorrect Authority): EXPECTED BEHAVIOR
└─ Vulnerable: Unauthorized access ✓
└─ Fixed: Authorization enforced ✓
⚠️ Attack Demo #03 (Unsafe Arithmetic): EXPECTED BEHAVIOR
└─ Vulnerable: Integer underflow ✓
└─ Fixed: Checked math prevented ✓
⚠️ Attack Demo #05 (Privilege Escalation): EXPECTED BEHAVIOR
└─ Vulnerable: Privilege escalation ✓
└─ Fixed: Access denied ✓
✅ All security tests passed
```
**预期行为:**
- ✅ **易受攻击的版本**:攻击成功(演示漏洞)
- ✅ **修复后的版本**:攻击被阻止(演示安全修复)
- ❌ **意外情况**:如果易受攻击的版本阻止了攻击,或者修复后的版本允许了攻击
### 贡献测试修改
在做贡献时,请确保:
1. 提交 PR 前所有工作流均通过
2. 新漏洞包含相应的测试
3. 攻击脚本演示了漏洞版本和修复版本的行为
4. 新功能的文档已更新
CI 将自动:
- 构建您的修改
- 运行所有安全测试
- 将结果作为 PR 评论发布
- 验证文档更新
## 学习路径
### 对于初学者
1. **从概念理解开始:**
- 阅读 [SECURITY.md](SECURITY.md) 了解漏洞概述
- 理解 Solana 账户模型:[Solana Docs](https://docs.solana.com/developing/programming-model/accounts)
2. **一次研究一个漏洞:**
- 从 `01-missing-account-validation` 开始
- 阅读示例 README
- 比较 `example1.rs`(易受攻击)和 `example1.fix.rs`(安全)
- 注意解释每个问题的内联注释
3. **运行攻击演示:**
- 执行相应的攻击脚本
- 观察攻击是如何运作的
- 看看为什么修复能阻止它
4. **构建并测试:**
- 编译易受攻击和修复后的程序
- 运行 Anchor 测试
- 尝试修改代码以破坏修复
### 对于中级开发者
1. **深入研究程序实现:**
- 学习 `programs/` 中的完整程序
- 理解 Anchor 账户约束
- 审查攻击者程序以了解真实的漏洞利用代码
2. **编写自己的漏洞利用:**
- 创建自定义攻击交易
- 测试边缘情况
- 记录新的攻击向量
3. **贡献改进:**
- 添加新的漏洞示例
- 完善文档
- 提交测试用例
### 对于安全审计人员
1. **研究漏洞模式:**
- 识别代码中的常见指标
- 学习 Anchor 特定的安全约束
- 理解 Solana 运行时的行为
2. **练习检测:**
- 在不看修复的情况下审查程序
- 识别所有漏洞
- 提出补救策略
3. **扩展知识库:**
- 添加真实的漏洞示例
- 记录高级攻击技术
- 分享审计发现(经过匿名化处理)
## 贡献指南
我们欢迎任何能够提升本仓库教育价值的贡献!
### 贡献什么
✅ **鼓励的贡献:**
- 带有详细说明的新漏洞示例
- 改进的文档和教程
- 额外的攻击演示
- 测试用例和边缘情况
- 翻译成其他语言
- Bug 和拼写错误更正
❌ **不鼓励的贡献:**
- 生产级代码(这仅用于教育)
- 删除漏洞示例
- 在不准确的前提下简化安全解释
- 添加没有明确教育价值的依赖项
### 如何贡献
1. **Fork 仓库**
2. **创建功能分支:**
```
git checkout -b feature/new-vulnerability-example
```
3. **遵循现有结构:**
- 漏洞版本:`example{n}.rs`
- 修复版本:`example{n}.fix.rs`
- 包含攻击演练的完整 README
- 解释每个步骤的内联注释
4. **测试您的代码:**
```
anchor build
anchor test
```
5. **提交 Pull Request**,需包含:
- 清晰的漏洞描述
- 教育价值的解释
- 测试证据
- 相关资源的链接
### 代码风格
- **注释:** 解释“为什么”,而不仅仅是“是什么”
- **命名:** 使用具有描述性的变量和函数名
- **结构:** 遵循 Anchor 最佳实践
- **文档:** 使用格式规范的 Markdown,并使用带有语言标签的代码块
## 资源
### 官方文档
- **Solana Docs:** https://docs.solana.com/
- **Anchor Lang:** https://www.anchor-lang.com/docs/
- **Pinocchio:** https://github.com/anza-xyz/pinocchio
### 安全资源
- **Solana Security Best Practices:** https://docs.solana.com/developping/programming-model/security
- **Anchor Security Guidelines:** https://www.anchor-lang.com/docs/security
- **Neodyme Security Blog:** https://blog.neodyme.io/
- **Sec3 Blog:** https://www.sec3.dev/blog
### 学习材料
- **Solana Cookbook:** https://solanacookbook.com/
- **Anchor by Example:** https://examples.anchor-lang.com/
- **Buildspace Solana Course:** https://buildspace.so/solana
### 审计报告
- **Solana Program Library Audits:** https://github.com/solana-labs/solana-program-library/tree/master/audit
- **真实的漏洞披露:** 来自各家安全公司和漏洞赏金平台
## 许可证
MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
## 免责声明
**⚠️ 仅供教育使用**
本仓库包含出于教育目的而故意设置漏洞的代码。切勿将这些程序部署到生产环境或将其与真实资金结合使用。作者对任何滥用此代码的行为概不负责。
## 致谢
- 感谢 Anchor 团队提供优秀的框架和安全原语
- 感谢 Solana Foundation 提供详尽的文档
- 感谢披露漏洞并启发这些示例的安全研究人员
- 感谢 SuperteamNG 提供指导编写这份详尽文档的赏金要求
**发现了此处未涵盖的漏洞?** 提交 issue 或提交 PR 来帮助他人学习!
标签:Solana, 区块链安全, 可视化界面, 安全教育, 智能合约, 漏洞分析, 路径探测, 通知系统