substrate-vulnerability-scanner by trailofbits/skills
npx skills add https://github.com/trailofbits/skills --skill substrate-vulnerability-scanner系统性地扫描 Substrate 运行时模块(Pallets),查找可能导致节点崩溃、DoS 攻击或未授权访问的平台特定安全漏洞。此技能编码了 7 种 Substrate/FRAME 链独有的关键漏洞模式。
.rs// Substrate/FRAME 标识符
#[pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config { }
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(10_000)]
pub fn example_function(origin: OriginFor<T>) -> DispatchResult { }
}
}
// 常见模式
DispatchResult, DispatchError
ensure!, ensure_signed, ensure_root
StorageValue, StorageMap, StorageDoubleMap
#[pallet::storage]
#[pallet::call]
#[pallet::weight]
#[pallet::validate_unsigned]
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
pallets/*/lib.rs - Pallet 实现runtime/lib.rs - 运行时配置benchmarking.rs - 权重基准测试Cargo.toml 中包含 frame-* 依赖调用此技能时,我将:
我检查 Substrate/FRAME 独有的 7 种关键漏洞模式。有关详细的检测模式、代码示例、缓解措施和测试策略,请参阅 VULNERABILITY_PATTERNS.md。
算术溢出 ⚠️ 严重
+、-、*、/ 运算符在发布模式下会回绕checked_* 或 saturating_* 方法禁止恐慌 ⚠️ 严重 - DoS
unwrap()、expect(),不进行无边界检查的数组索引ensure! 验证权重与费用 ⚠️ 严重 - DoS
先验证,后写入 ⚠️ 高(v0.9.25 之前版本)
#[transactional]未签名交易验证 ⚠️ 高
不良随机性 ⚠️ 中
pallet_randomness_collective_flip 易受合谋攻击pallet_babe::RandomnessFromOneEpochAgo)random(subject) 而非 random_seed()不良来源 ⚠️ 严重
ensure_signed 允许任何用户执行特权操作ensure_root 或自定义来源(ForceOrigin, AdminOrigin)有关包含代码示例的完整漏洞模式,请参阅 VULNERABILITY_PATTERNS.md。
pallets/*/lib.rs)runtime/lib.rs)针对每个 #[pallet::call] 函数:
# 搜索易导致恐慌的模式
rg "unwrap\(\)" pallets/
rg "expect\(" pallets/
rg "\[.*\]" pallets/ # 数组索引
rg " as u\d+" pallets/ # 类型转换
rg "\.unwrap_or" pallets/
# 查找直接算术运算
rg " \+ |\+=| - |-=| \* |\*=| / |/=" pallets/
# 应该找到 checked/saturating 替代方法
rg "checked_add|checked_sub|checked_mul|checked_div" pallets/
rg "saturating_add|saturating_sub|saturating_mul" pallets/
cargo test --features runtime-benchmarks# 查找特权操作
rg "ensure_signed" pallets/ | grep -E "pause|emergency|admin|force|sudo"
# 应该使用 ensure_root 或自定义来源
rg "ensure_root|ForceOrigin|AdminOrigin" pallets/
// 使用 test-fuzz 进行基于属性的测试
#[cfg(test)]
mod tests {
use test_fuzz::test_fuzz;
#[test_fuzz]
fn fuzz_transfer(from: AccountId, to: AccountId, amount: u128) {
// 永远不应恐慌
let _ = Pallet::transfer(from, to, amount);
}
#[test_fuzz]
fn fuzz_no_panics(call: Call) {
// 任何可调度函数都不应恐慌
let _ = call.dispatch(origin);
}
}
# 运行基准测试以生成权重
cargo build --release --features runtime-benchmarks
./target/release/node benchmark pallet \
--chain dev \
--pallet pallet_example \
--extrinsic "*" \
--steps 50 \
--repeat 20
# 测试运行时升级
cargo build --release --features try-runtime
try-runtime --runtime ./target/release/wbuild/runtime.wasm \
on-runtime-upgrade live --uri wss://rpc.polkadot.io
building-secure-contracts/not-so-smart-contracts/substrate/完成 Substrate pallet 审计前:
算术安全(严重) :
+、-、*、/ 运算符checked_* 或 saturating_*try_into() 并处理错误恐慌预防(严重) :
unwrap() 或 expect()ensure! 验证权重与 DoS(严重):
访问控制(严重) :
ensure_root 或自定义来源ensure_signed 仅用于用户级操作存储安全(高) :
#[transactional]其他(中) :
random(subject) 而非 random_seed()测试 :
每周安装量
1.0K
代码仓库
GitHub 星标数
3.9K
首次出现
2026年1月19日
安全审计
安装于
claude-code941
opencode900
gemini-cli886
codex880
cursor858
github-copilot828
Systematically scan Substrate runtime modules (pallets) for platform-specific security vulnerabilities that can cause node crashes, DoS attacks, or unauthorized access. This skill encodes 7 critical vulnerability patterns unique to Substrate/FRAME-based chains.
.rs// Substrate/FRAME indicators
#[pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config { }
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(10_000)]
pub fn example_function(origin: OriginFor<T>) -> DispatchResult { }
}
}
// Common patterns
DispatchResult, DispatchError
ensure!, ensure_signed, ensure_root
StorageValue, StorageMap, StorageDoubleMap
#[pallet::storage]
#[pallet::call]
#[pallet::weight]
#[pallet::validate_unsigned]
pallets/*/lib.rs - Pallet implementationsruntime/lib.rs - Runtime configurationbenchmarking.rs - Weight benchmarksCargo.toml with frame-* dependenciesWhen invoked, I will:
I check for 7 critical vulnerability patterns unique to Substrate/FRAME. For detailed detection patterns, code examples, mitigations, and testing strategies, see VULNERABILITY_PATTERNS.md.
Arithmetic Overflow ⚠️ CRITICAL
+, -, *, / operators wrap in release modechecked_* or saturating_* methodsDon't Panic ⚠️ CRITICAL - DoS
unwrap(), expect(), array indexing without bounds checkensure!For complete vulnerability patterns with code examples, see VULNERABILITY_PATTERNS.md.
pallets/*/lib.rs)runtime/lib.rs)For each #[pallet::call] function:
# Search for panic-prone patterns
rg "unwrap\(\)" pallets/
rg "expect\(" pallets/
rg "\[.*\]" pallets/ # Array indexing
rg " as u\d+" pallets/ # Type casts
rg "\.unwrap_or" pallets/
# Find direct arithmetic
rg " \+ |\+=| - |-=| \* |\*=| / |/=" pallets/
# Should find checked/saturating alternatives instead
rg "checked_add|checked_sub|checked_mul|checked_div" pallets/
rg "saturating_add|saturating_sub|saturating_mul" pallets/
cargo test --features runtime-benchmarks# Find privileged operations
rg "ensure_signed" pallets/ | grep -E "pause|emergency|admin|force|sudo"
# Should use ensure_root or custom origins
rg "ensure_root|ForceOrigin|AdminOrigin" pallets/
// Use test-fuzz for property-based testing
#[cfg(test)]
mod tests {
use test_fuzz::test_fuzz;
#[test_fuzz]
fn fuzz_transfer(from: AccountId, to: AccountId, amount: u128) {
// Should never panic
let _ = Pallet::transfer(from, to, amount);
}
#[test_fuzz]
fn fuzz_no_panics(call: Call) {
// No dispatchable should panic
let _ = call.dispatch(origin);
}
}
# Run benchmarks to generate weights
cargo build --release --features runtime-benchmarks
./target/release/node benchmark pallet \
--chain dev \
--pallet pallet_example \
--extrinsic "*" \
--steps 50 \
--repeat 20
# Test runtime upgrades
cargo build --release --features try-runtime
try-runtime --runtime ./target/release/wbuild/runtime.wasm \
on-runtime-upgrade live --uri wss://rpc.polkadot.io
building-secure-contracts/not-so-smart-contracts/substrate/Before completing Substrate pallet audit:
Arithmetic Safety (CRITICAL) :
+, -, *, / operators in dispatchableschecked_* or saturating_*try_into() with error handlingPanic Prevention (CRITICAL) :
unwrap() or expect() in dispatchablesensure!Weights & DoS (CRITICAL):
Access Control (CRITICAL) :
ensure_root or custom originsensure_signed only for user-level operationsStorage Safety (HIGH) :
#[transactional]Other (MEDIUM) :
random(subject) not random_seed()Testing :
Weekly Installs
1.0K
Repository
GitHub Stars
3.9K
First Seen
Jan 19, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
claude-code941
opencode900
gemini-cli886
codex880
cursor858
github-copilot828
Gemini Interactions API 指南:统一接口、智能体交互与服务器端状态管理
833 周安装
Apollo MCP 服务器:让AI代理通过GraphQL API交互的完整指南
834 周安装
智能体记忆系统构建指南:分块策略、向量存储与检索优化
835 周安装
Scrapling官方网络爬虫框架 - 自适应解析、绕过Cloudflare、Python爬虫库
836 周安装
抽奖赢家选取器 - 随机选择工具,支持CSV、Excel、Google Sheets,公平透明
838 周安装
Medusa 前端开发指南:使用 SDK、React Query 构建电商商店
839 周安装
Weights and Fees ⚠️ CRITICAL - DoS
Verify First, Write Last ⚠️ HIGH (Pre-v0.9.25)
#[transactional]Unsigned Transaction Validation ⚠️ HIGH
Bad Randomness ⚠️ MEDIUM
pallet_randomness_collective_flip vulnerable to collusionpallet_babe::RandomnessFromOneEpochAgo)random(subject) not random_seed()Bad Origin ⚠️ CRITICAL
ensure_signed allows any user for privileged operationsensure_root or custom origins (ForceOrigin, AdminOrigin)