cairo-vulnerability-scanner by trailofbits/skills
npx skills add https://github.com/trailofbits/skills --skill cairo-vulnerability-scanner系统性地扫描 StarkNet 上的 Cairo 智能合约,查找与算术运算、跨层消息传递和加密操作相关的平台特定安全漏洞。此技能编码了 6 个 Cairo/StarkNet 生态系统独有的关键漏洞模式。
.cairo// Cairo 合约标识
#[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
}
}
// 常见模式
felt252, u128, u256
ContractAddress, EthAddress
#[external(v0)], #[l1_handler], #[constructor]
get_caller_address(), get_contract_address()
send_message_to_l1_syscall
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
src/contract.cairo - 主合约实现src/lib.cairo - 库模块tests/ - 合约测试Scarb.toml - Cairo 项目配置pip install caracalcaracal detect src/调用时,我将:
当发现漏洞时,您将收到类似以下的报告:
=== CAIRO/STARKNET VULNERABILITY SCAN RESULTS ===
我检查 6 种 Cairo/Starknet 独有的关键漏洞模式。有关详细的检测模式、代码示例、缓解措施和测试策略,请参阅 VULNERABILITY_PATTERNS.md。
有关包含代码示例的完整漏洞模式,请参阅 VULNERABILITY_PATTERNS.md。
src/*.cairo)# 查找算术运算中的 felt252 使用
rg "felt252" src/ | rg "[-+*/]"
# 查找使用 felt252 的余额/金额存储
rg "felt252" src/ | rg "balance|amount|total|supply"
# 应优先使用 u128, u256 代替
针对每个 #[l1_handler] 函数:
from_address 参数针对基于签名的函数:
如果合约包含桥接功能:
# 运行 Caracal 检测器
caracal detect src/
# 特定检测器
caracal detect src/ --detectors unchecked-felt252-arithmetic
caracal detect src/ --detectors unchecked-l1-handler-from
caracal detect src/ --detectors missing-nonce-validation
## [严重] L1 处理函数中未检查的 from_address
**位置**:`src/bridge.cairo:145-155` (handle_deposit 函数)
**描述**:
`handle_deposit` L1 处理函数未验证 `from_address` 参数。任何 L1 合约都可以向此函数发送消息并为任意用户铸造代币,从而绕过预期的 L1 桥接访问控制。
**易受攻击的代码**:
```rust
// bridge.cairo, 第 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);
}
攻击场景:
starknetCore.sendMessageToL2(l2Contract, selector, [attacker_address, 1000000])建议:根据授权的 L1 桥接验证 from_address:
#[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);
}
参考资料:
unchecked-l1-handler-from#[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
}
}
// 测试完整的 L1-L2 流程
#[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
}
# .github/workflows/security.yml
- name: Run Caracal
run: |
pip install caracal
caracal detect src/ --fail-on high,critical
building-secure-contracts/not-so-smart-contracts/cairo/完成 Cairo/StarkNet 审计前:
算术安全性(高危):
L1 处理函数安全性(严重):
#[l1_handler] 函数都验证 from_addressL1-L2 消息传递(高危):
签名安全性(高危):
工具使用:
每周安装量
1.1K
仓库
GitHub 星标
3.9K
首次出现
Jan 19, 2026
安全审计
安装于
claude-code986
opencode940
gemini-cli926
codex920
cursor898
github-copilot868
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.
.cairo// 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_syscall
src/contract.cairo - Main contract implementationsrc/lib.cairo - Library modulestests/ - Contract testsScarb.toml - Cairo project configurationpip install caracalcaracal detect src/When invoked, I will:
When vulnerabilities are found, you'll get a report like this:
=== CAIRO/STARKNET VULNERABILITY SCAN RESULTS ===
---
## 5. Vulnerability Patterns (6 Patterns)
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](resources/VULNERABILITY_PATTERNS.md).
### Pattern Summary:
1. **Unchecked Arithmetic** ⚠️ CRITICAL - Integer overflow/underflow in felt252
2. **Storage Collision** ⚠️ CRITICAL - Conflicting storage variable hashes
3. **Missing Access Control** ⚠️ CRITICAL - No caller validation on sensitive functions
4. **Improper Felt252 Boundaries** ⚠️ HIGH - Not validating felt252 range
5. **Unvalidated Contract Address** ⚠️ HIGH - Using untrusted contract addresses
6. **Missing Caller Validation** ⚠️ CRITICAL - No get_caller_address() checks
For complete vulnerability patterns with code examples, see [VULNERABILITY_PATTERNS.md](resources/VULNERABILITY_PATTERNS.md).
## 5. Scanning Workflow
### Step 1: Platform Identification
1. Verify Cairo language and StarkNet framework
2. Check Cairo version (Cairo 1.0+ vs legacy Cairo 0)
3. Locate contract files (`src/*.cairo`)
4. Identify L1-L2 bridge contracts (if applicable)
### Step 2: Arithmetic Safety Sweep
```bash
# Find felt252 usage in arithmetic
rg "felt252" src/ | rg "[-+*/]"
# Find balance/amount storage using felt252
rg "felt252" src/ | rg "balance|amount|total|supply"
# Should prefer u128, u256 instead
For each #[l1_handler] function:
from_address parameterFor signature-based functions:
If contract includes bridge functionality:
# Run Caracal detectors
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
## [CRITICAL] Unchecked from_address in L1 Handler
**Location**: `src/bridge.cairo:145-155` (handle_deposit function)
**Description**:
The `handle_deposit` L1 handler function does not validate the `from_address` parameter. Any L1 contract can send messages to this function and mint tokens for arbitrary users, bypassing the intended L1 bridge access controls.
**Vulnerable 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 :
starknetCore.sendMessageToL2(l2Contract, selector, [attacker_address, 1000000])Recommendation : Validate from_address against authorized L1 bridge:
#[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
#[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
}
}
// 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
}
# .github/workflows/security.yml
- name: Run Caracal
run: |
pip install caracal
caracal detect src/ --fail-on high,critical
building-secure-contracts/not-so-smart-contracts/cairo/Before completing Cairo/StarkNet audit:
Arithmetic Safety (HIGH) :
L1 Handler Security (CRITICAL) :
#[l1_handler] functions validate from_addressL1-L2 Messaging (HIGH) :
Signature Security (HIGH) :
Tool Usage :
Weekly Installs
1.1K
Repository
GitHub Stars
3.9K
First Seen
Jan 19, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykPass
Installed on
claude-code986
opencode940
gemini-cli926
codex920
cursor898
github-copilot868
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
102,200 周安装
网页无障碍性(a11y)最佳实践指南:遵循WCAG标准,提升网站包容性设计
1,000 周安装
AI Logo Creator - 使用 Gemini 和 Recraft 生成专业标志设计
1,000 周安装
Rust编码指南50条核心规则:命名、内存、并发、错误处理最佳实践
1,000 周安装
RAG 架构师指南:构建高效检索增强生成系统,优化向量存储与分块策略
1,000 周安装
marimo Python笔记本教程:交互式数据科学工具,替代Jupyter的响应式开发
1,000 周安装
RivetKit多人游戏开发模式:大逃杀、竞技场、IO游戏等10类模板与物理引擎指南
1,000 周安装