cairo-vulnerability-scanner
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCairo/StarkNet Vulnerability Scanner
Cairo/StarkNet漏洞扫描工具
1. Purpose
1. 用途
Systematically scan Cairo smart contracts on StarkNet for platform-specific security vulnerabilities related to arithmetic, cross-layer messaging, and cryptographic operations. This skill encodes 6 critical vulnerability patterns unique to Cairo/StarkNet ecosystem.
系统性扫描StarkNet上的Cairo智能合约,查找与算术运算、跨层消息传递和加密操作相关的平台特定安全漏洞。本技能涵盖了Cairo/StarkNet生态系统特有的6种关键漏洞模式。
2. When to Use This Skill
2. 何时使用本技能
- Auditing StarkNet smart contracts (Cairo)
- Reviewing L1-L2 bridge implementations
- Pre-launch security assessment of StarkNet applications
- Validating cross-layer message handling
- Reviewing signature verification logic
- Assessing L1 handler functions
- 审计StarkNet智能合约(Cairo)
- 审查L1-L2桥接实现
- StarkNet应用上线前的安全评估
- 验证跨层消息处理逻辑
- 审查签名验证逻辑
- 评估L1处理函数
3. Platform Detection
3. 平台检测
File Extensions & Indicators
文件扩展名与识别标志
- Cairo files:
.cairo
- Cairo文件:
.cairo
Language/Framework Markers
语言/框架标记
rust
// Cairo contract indicators
#[contract]
mod MyContract {
use starknet::ContractAddress;
#[storage]
struct Storage {
balance: LegacyMap<ContractAddress, felt252>,
}
#[external(v0)]
fn transfer(ref self: ContractState, to: ContractAddress, amount: felt252) {
// Contract logic
}
#[l1_handler]
fn handle_deposit(ref self: ContractState, from_address: felt252, amount: u256) {
// L1 message handler
}
}
// Common patterns
felt252, u128, u256
ContractAddress, EthAddress
#[external(v0)], #[l1_handler], #[constructor]
get_caller_address(), get_contract_address()
send_message_to_l1_syscallrust
// Cairo contract indicators
#[contract]
mod MyContract {
use starknet::ContractAddress;
#[storage]
struct Storage {
balance: LegacyMap<ContractAddress, felt252>,
}
#[external(v0)]
fn transfer(ref self: ContractState, to: ContractAddress, amount: felt252) {
// Contract logic
}
#[l1_handler]
fn handle_deposit(ref self: ContractState, from_address: felt252, amount: u256) {
// L1 message handler
}
}
// Common patterns
felt252, u128, u256
ContractAddress, EthAddress
#[external(v0)], #[l1_handler], #[constructor]
get_caller_address(), get_contract_address()
send_message_to_l1_syscallProject Structure
项目结构
- - Main contract implementation
src/contract.cairo - - Library modules
src/lib.cairo - - Contract tests
tests/ - - Cairo project configuration
Scarb.toml
- - 主合约实现
src/contract.cairo - - 库模块
src/lib.cairo - - 合约测试
tests/ - - Cairo项目配置文件
Scarb.toml
Tool Support
工具支持
- Caracal: Trail of Bits static analyzer for Cairo
- Installation:
pip install caracal - Usage:
caracal detect src/ - cairo-test: Built-in testing framework
- Starknet Foundry: Testing and development toolkit
- Caracal: Trail of Bits推出的Cairo静态分析器
- 安装:
pip install caracal - 使用:
caracal detect src/ - cairo-test: 内置测试框架
- Starknet Foundry: 测试与开发工具包
4. How This Skill Works
4. 本技能工作原理
When invoked, I will:
- Search your codebase for Cairo files
- Analyze each contract for the 6 vulnerability patterns
- Report findings with file references and severity
- Provide fixes for each identified issue
- Check L1-L2 interactions for messaging vulnerabilities
调用本技能时,我会:
- 搜索代码库中的Cairo文件
- 分析每个合约,查找6种漏洞模式
- 报告检测结果,包含文件引用和风险等级
- 提供修复方案针对每个发现的问题
- 检查L1-L2交互中的消息传递漏洞
5. Example Output
5. 示例输出
When vulnerabilities are found, you'll get a report like this:
=== CAIRO/STARKNET VULNERABILITY SCAN RESULTS ===
---当检测到漏洞时,你将收到如下报告:
=== CAIRO/STARKNET VULNERABILITY SCAN RESULTS ===
---5. Vulnerability Patterns (6 Patterns)
5. 漏洞模式(6种)
I check for 6 critical vulnerability patterns unique to Cairo/Starknet. For detailed detection patterns, code examples, mitigations, and testing strategies, see VULNERABILITY_PATTERNS.md.
我会检查Cairo/Starknet特有的6种关键漏洞模式。如需详细的检测模式、代码示例、缓解措施和测试策略,请查看VULNERABILITY_PATTERNS.md。
Pattern Summary:
模式摘要:
- Unchecked Arithmetic ⚠️ CRITICAL - Integer overflow/underflow in felt252
- Storage Collision ⚠️ CRITICAL - Conflicting storage variable hashes
- Missing Access Control ⚠️ CRITICAL - No caller validation on sensitive functions
- Improper Felt252 Boundaries ⚠️ HIGH - Not validating felt252 range
- Unvalidated Contract Address ⚠️ HIGH - Using untrusted contract addresses
- Missing Caller Validation ⚠️ CRITICAL - No get_caller_address() checks
For complete vulnerability patterns with code examples, see VULNERABILITY_PATTERNS.md.
- 未检查的算术运算 ⚠️ 严重 - felt252中的整数溢出/下溢
- 存储冲突 ⚠️ 严重 - 存储变量哈希冲突
- 缺失访问控制 ⚠️ 严重 - 敏感函数未验证调用者
- 不当的Felt252边界 ⚠️ 高风险 - 未验证felt252范围
- 未验证的合约地址 ⚠️ 高风险 - 使用不可信的合约地址
- 缺失调用者验证 ⚠️ 严重 - 未执行get_caller_address()检查
如需包含代码示例的完整漏洞模式,请查看VULNERABILITY_PATTERNS.md。
5. Scanning Workflow
5. 扫描流程
Step 1: Platform Identification
步骤1:平台识别
- Verify Cairo language and StarkNet framework
- Check Cairo version (Cairo 1.0+ vs legacy Cairo 0)
- Locate contract files ()
src/*.cairo - Identify L1-L2 bridge contracts (if applicable)
- 验证Cairo语言和StarkNet框架
- 检查Cairo版本(Cairo 1.0+ 对比旧版Cairo 0)
- 定位合约文件()
src/*.cairo - 识别L1-L2桥接合约(如适用)
Step 2: Arithmetic Safety Sweep
步骤2:算术安全扫描
bash
undefinedbash
undefinedFind felt252 usage in arithmetic
查找算术运算中的felt252使用
rg "felt252" src/ | rg "[-+*/]"
rg "felt252" src/ | rg "[-+*/]"
Find balance/amount storage using felt252
查找使用felt252的余额/金额存储
rg "felt252" src/ | rg "balance|amount|total|supply"
rg "felt252" src/ | rg "balance|amount|total|supply"
Should prefer u128, u256 instead
应优先使用u128, u256
undefinedundefinedStep 3: L1 Handler Analysis
步骤3:L1处理函数分析
For each function:
#[l1_handler]- Validates parameter
from_address - Checks address != zero
- Has proper access control
- Emits events for monitoring
针对每个函数:
#[l1_handler]- 验证参数
from_address - 检查地址不为零
- 具备适当的访问控制
- 触发事件以便监控
Step 4: Signature Verification Review
步骤4:签名验证审查
For signature-based functions:
- Includes nonce tracking
- Nonce incremented after use
- Domain separator includes chain ID and contract address
- Cannot replay signatures
针对基于签名的函数:
- 包含随机数(nonce)跟踪
- 使用后递增随机数
- 域分隔符包含链ID和合约地址
- 防止签名重放
Step 5: L1-L2 Bridge Audit
步骤5:L1-L2桥接审计
If contract includes bridge functionality:
- L1 validates address < STARKNET_FIELD_PRIME
- L1 implements message cancellation
- L2 validates from_address in handlers
- Symmetric access controls L1 ↔ L2
- Test full roundtrip flows
如果合约包含桥接功能:
- L1验证地址 < STARKNET_FIELD_PRIME
- L1实现消息取消机制
- L2处理函数验证from_address
- L1 ↔ L2采用对称访问控制
- 测试完整的往返流程
Step 6: Static Analysis with Caracal
步骤6:使用Caracal进行静态分析
bash
undefinedbash
undefinedRun Caracal detectors
运行Caracal检测器
caracal detect src/
caracal detect src/
Specific detectors
指定检测器
caracal detect src/ --detectors unchecked-felt252-arithmetic
caracal detect src/ --detectors unchecked-l1-handler-from
caracal detect src/ --detectors missing-nonce-validation
---caracal detect src/ --detectors unchecked-felt252-arithmetic
caracal detect src/ --detectors unchecked-l1-handler-from
caracal detect src/ --detectors missing-nonce-validation
---6. Reporting Format
6. 报告格式
Finding Template
检测结果模板
markdown
undefinedmarkdown
undefined[CRITICAL] Unchecked from_address in L1 Handler
[严重] L1处理函数中未检查from_address
Location: (handle_deposit function)
src/bridge.cairo:145-155Description:
The L1 handler function does not validate the parameter. Any L1 contract can send messages to this function and mint tokens for arbitrary users, bypassing the intended L1 bridge access controls.
handle_depositfrom_addressVulnerable Code:
rust
// bridge.cairo, line 145
#[l1_handler]
fn handle_deposit(
ref self: ContractState,
from_address: felt252, // Not validated!
user: ContractAddress,
amount: u256
) {
let current_balance = self.balances.read(user);
self.balances.write(user, current_balance + amount);
}Attack Scenario:
- Attacker deploys malicious L1 contract
- Malicious contract calls
starknetCore.sendMessageToL2(l2Contract, selector, [attacker_address, 1000000]) - L2 handler processes message without checking sender
- Attacker receives 1,000,000 tokens without depositing any funds
- Protocol suffers infinite mint vulnerability
Recommendation:
Validate against authorized L1 bridge:
from_addressrust
#[l1_handler]
fn handle_deposit(
ref self: ContractState,
from_address: felt252,
user: ContractAddress,
amount: u256
) {
// Validate L1 sender
let authorized_l1_bridge = self.l1_bridge_address.read();
assert(from_address == authorized_l1_bridge, 'Unauthorized L1 sender');
let current_balance = self.balances.read(user);
self.balances.write(user, current_balance + amount);
}References:
- building-secure-contracts/not-so-smart-contracts/cairo/unchecked_l1_handler_from
- Caracal detector:
unchecked-l1-handler-from
---位置: (handle_deposit函数)
src/bridge.cairo:145-155描述:
L1处理函数未验证参数。任何L1合约都可以向该函数发送消息,为任意用户铸造代币,绕过预期的L1桥接访问控制。
handle_depositfrom_address漏洞代码:
rust
// bridge.cairo, line 145
#[l1_handler]
fn handle_deposit(
ref self: ContractState,
from_address: felt252, // 未验证!
user: ContractAddress,
amount: u256
) {
let current_balance = self.balances.read(user);
self.balances.write(user, current_balance + amount);
}攻击场景:
- 攻击者部署恶意L1合约
- 恶意合约调用
starknetCore.sendMessageToL2(l2Contract, selector, [attacker_address, 1000000]) - L2处理函数在未检查发送者的情况下处理消息
- 攻击者无需存入任何资金即可获得1,000,000枚代币
- 协议遭受无限铸造漏洞
修复建议:
针对授权的L1桥接验证:
from_addressrust
#[l1_handler]
fn handle_deposit(
ref self: ContractState,
from_address: felt252,
user: ContractAddress,
amount: u256
) {
// 验证L1发送者
let authorized_l1_bridge = self.l1_bridge_address.read();
assert(from_address == authorized_l1_bridge, 'Unauthorized L1 sender');
let current_balance = self.balances.read(user);
self.balances.write(user, current_balance + amount);
}参考资料:
- building-secure-contracts/not-so-smart-contracts/cairo/unchecked_l1_handler_from
- Caracal检测器:
unchecked-l1-handler-from
---7. Priority Guidelines
7. 优先级指南
Critical (Immediate Fix Required)
严重(需立即修复)
- Unchecked from_address in L1 handlers (infinite mint)
- L1-L2 address conversion issues (funds to zero address)
- L1处理函数中未检查from_address(无限铸造)
- L1-L2地址转换问题(资金转入零地址)
High (Fix Before Deployment)
高风险(部署前修复)
- Felt252 arithmetic overflow/underflow (balance manipulation)
- Missing signature replay protection (replay attacks)
- L1-L2 message failure without cancellation (locked funds)
- Felt252算术溢出/下溢(余额操纵)
- 缺失签名重放防护(重放攻击)
- L1-L2消息传递失败且无取消机制(资金锁定)
Medium (Address in Audit)
中风险(审计中处理)
- Overconstrained L1-L2 interactions (trapped funds)
- L1-L2交互过度约束(资金被困)
8. Testing Recommendations
8. 测试建议
Unit Tests
单元测试
rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_felt252_overflow() {
// Test arithmetic edge cases
}
#[test]
#[should_panic]
fn test_unauthorized_l1_handler() {
// Wrong from_address should fail
}
#[test]
fn test_signature_replay_protection() {
// Same signature twice should fail
}
}rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_felt252_overflow() {
// 测试算术边界情况
}
#[test]
#[should_panic]
fn test_unauthorized_l1_handler() {
// 错误的from_address应触发panic
}
#[test]
fn test_signature_replay_protection() {
// 相同签名使用两次应失败
}
}Integration Tests (with L1)
集成测试(与L1联动)
rust
// Test full L1-L2 flow
#[test]
fn test_deposit_withdraw_roundtrip() {
// 1. Deposit on L1
// 2. Wait for L2 processing
// 3. Verify L2 balance
// 4. Withdraw to L1
// 5. Verify L1 balance restored
}rust
// 测试完整的L1-L2流程
#[test]
fn test_deposit_withdraw_roundtrip() {
// 1. 在L1存入资金
// 2. 等待L2处理
// 3. 验证L2余额
// 4. 提取资金到L1
// 5. 验证L1余额恢复
}Caracal CI Integration
Caracal CI集成
yaml
undefinedyaml
undefined.github/workflows/security.yml
.github/workflows/security.yml
- name: Run Caracal run: | pip install caracal caracal detect src/ --fail-on high,critical
---- name: Run Caracal run: | pip install caracal caracal detect src/ --fail-on high,critical
---9. Additional Resources
9. 额外资源
- Building Secure Contracts:
building-secure-contracts/not-so-smart-contracts/cairo/ - Caracal: https://github.com/crytic/caracal
- Cairo Documentation: https://book.cairo-lang.org/
- StarkNet Documentation: https://docs.starknet.io/
- OpenZeppelin Cairo Contracts: https://github.com/OpenZeppelin/cairo-contracts
- Building Secure Contracts:
building-secure-contracts/not-so-smart-contracts/cairo/ - Caracal: https://github.com/crytic/caracal
- Cairo文档: https://book.cairo-lang.org/
- StarkNet文档: https://docs.starknet.io/
- OpenZeppelin Cairo合约: https://github.com/OpenZeppelin/cairo-contracts
10. Quick Reference Checklist
10. 快速参考检查清单
Before completing Cairo/StarkNet audit:
Arithmetic Safety (HIGH):
- No felt252 used for balances/amounts (use u128/u256)
- OR felt252 arithmetic has explicit bounds checking
- Overflow/underflow scenarios tested
L1 Handler Security (CRITICAL):
- ALL functions validate
#[l1_handler]from_address - from_address compared against stored L1 contract address
- Cannot bypass by deploying alternate L1 contract
L1-L2 Messaging (HIGH):
- L1 bridge validates addresses < STARKNET_FIELD_PRIME
- L1 bridge implements message cancellation
- L2 handlers check from_address
- Symmetric validation rules L1 ↔ L2
- Full roundtrip flows tested
Signature Security (HIGH):
- Signatures include nonce tracking
- Nonce incremented after each use
- Domain separator includes chain ID and contract address
- Signature replay tested and prevented
- Cross-chain replay prevented
Tool Usage:
- Caracal scan completed with no critical findings
- Unit tests cover all vulnerability scenarios
- Integration tests verify L1-L2 flows
- Testnet deployment tested before mainnet
完成Cairo/StarkNet审计前:
算术安全(高风险):
- 未使用felt252存储余额/金额(改用u128/u256)
- 或felt252算术运算有明确的边界检查
- 溢出/下溢场景已测试
L1处理函数安全(严重):
- 所有函数都验证
#[l1_handler]from_address - from_address与存储的L1合约地址对比
- 无法通过部署替代L1合约绕过验证
L1-L2消息传递(高风险):
- L1桥接验证地址 < STARKNET_FIELD_PRIME
- L1桥接实现消息取消机制
- L2处理函数检查from_address
- L1 ↔ L2采用对称验证规则
- 完整的往返流程已测试
签名安全(高风险):
- 签名包含随机数(nonce)跟踪
- 每次使用后递增随机数
- 域分隔符包含链ID和合约地址
- 签名重放已测试并阻止
- 跨链重放已阻止
工具使用:
- 已完成Caracal扫描且无严重发现
- 单元测试覆盖所有漏洞场景
- 集成测试验证L1-L2流程
- 主网上线前已在测试网部署测试
undefined