solana-vulnerability-scanner
Solanaプログラムを対象に、任意のCPI、不適切なPDA検証、署名者・所有権チェックの欠落、sysvarスプーフィングなど6種類の重大な脆弱性をスキャンします。Solana/Anchorプログラムのセキュリティ監査を行う際に使用してください。
description の原文を見る
Scans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing. Use when auditing Solana/Anchor programs.
SKILL.md 本文
Solana Vulnerability Scanner
1. Purpose
Solana プログラム(ネイティブおよび Anchor フレームワーク)をシステマティックにスキャンし、クロスプログラム呼び出し、アカウント検証、プログラム派生アドレスに関連するプラットフォーム固有のセキュリティ脆弱性を検出します。このスキルは Solana のアカウントモデルに固有の 6 つの重大な脆弱性パターンをエンコードしています。
2. When to Use This Skill
- Solana プログラムの監査(ネイティブ Rust または Anchor)
- クロスプログラム呼び出し(CPI)ロジックのレビュー
- プログラム派生アドレス(PDA)実装の検証
- Solana プロトコルのローンチ前セキュリティ評価
- アカウント検証パターンのレビュー
- 命令イントロスペクションロジックの評価
3. Platform Detection
File Extensions & Indicators
- Rust files:
.rs
Language/Framework Markers
// Native Solana program indicators
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
program::invoke,
program::invoke_signed,
};
entrypoint!(process_instruction);
// Anchor framework indicators
use anchor_lang::prelude::*;
#[program]
pub mod my_program {
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// Program logic
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub authority: Signer<'info>,
}
// Common patterns
AccountInfo, Pubkey
invoke(), invoke_signed()
Signer<'info>, Account<'info>
#[account(...)] with constraints
seeds, bump
Project Structure
programs/*/src/lib.rs- プログラム実装Anchor.toml- Anchor 設定Cargo.tomlwithsolana-programoranchor-langtests/- プログラムテスト
Tool Support
- Trail of Bits Solana Lints: Solana 向け Rust リンター
- Installation: Cargo.toml に追加
- anchor test: 組み込みテストフレームワーク
- Solana Test Validator: ローカルテスト環境
4. How This Skill Works
呼び出されると、以下を実施します:
- コードベースを検索 - Solana/Anchor プログラムを探索
- 各プログラムを分析 - 6 つの脆弱性パターンを検出
- 検出結果をレポート - ファイル参照と重大度を記載
- 修正を提供 - 特定された各問題の修正方法を提示
- アカウント検証と CPI セキュリティをチェック
5. Example Output
6. Vulnerability Patterns (6 Patterns)
Solana に固有の 6 つの重大な脆弱性パターンをチェックします。詳細な検出パターン、コード例、軽減策、テスト戦略については、VULNERABILITY_PATTERNS.md を参照してください。
Pattern Summary:
- Arbitrary CPI ⚠️ CRITICAL - CPI 呼び出しでユーザー制御のプログラム ID が使用される
- Improper PDA Validation ⚠️ CRITICAL - 正規の bump なしで create_program_address を使用
- Missing Ownership Check ⚠️ HIGH - 所有者検証なしでアカウントをデシリアライズ
- Missing Signer Check ⚠️ CRITICAL - is_signer チェックなしでの権限操作
- Sysvar Account Check ⚠️ HIGH - スプーフされた sysvar アカウント(Solana 1.8.1 以前)
- Improper Instruction Introspection ⚠️ MEDIUM - 再利用を許可する絶対インデックス
完全な脆弱性パターンとコード例については、VULNERABILITY_PATTERNS.md を参照してください。
7. Scanning Workflow
Step 1: Platform Identification
- Solana プログラムを確認(ネイティブまたは Anchor)
- Solana バージョンを確認(sysvar セキュリティのために 1.8.1 以上)
- プログラムソースを特定(
programs/*/src/lib.rs) - フレームワークを特定(ネイティブ vs Anchor)
Step 2: CPI Security Review
# すべての CPI 呼び出しを検索
rg "invoke\(|invoke_signed\(" programs/
# 各呼び出しの前にプログラム ID 検証を確認
# invoke の直前にプログラム ID チェックが必要
各 CPI について:
- プログラム ID が invocation の前に検証されている
- ユーザー制御のプログラムアカウントを渡せない
- Anchor:
Program<'info, T>タイプを使用
Step 3: PDA Validation Check
# PDA の使用を検索
rg "find_program_address|create_program_address" programs/
rg "seeds.*bump" programs/
# Anchor: seeds 制約を確認
rg "#\[account.*seeds" programs/
各 PDA について:
-
find_program_address()または Anchorseeds制約を使用 - Bump シードが保存および再利用されている
- ユーザーが提供した bump を使用していない
Step 4: Account Validation Sweep
# アカウント デシリアライズを検索
rg "try_from_slice|try_deserialize" programs/
# デシリアライズ前に所有者チェックが必要
rg "\.owner\s*==|\.owner\s*!=" programs/
使用された各アカウント について:
- デシリアライズ前に所有者が検証されている
- 権限アカウントの署名者チェック
- Anchor:
Account<'info, T>とSigner<'info>を使用
Step 5: Instruction Introspection Review
# 命令イントロスペクション使用を検索
rg "load_instruction_at|load_current_index|get_instruction_relative" programs/
# チェック済みバージョンを確認
rg "load_instruction_at_checked|load_current_index_checked" programs/
- チェック済み関数を使用(Solana 1.8.1 以上)
- 相対インデックスを使用
- 適切な関連付け検証
Step 6: Trail of Bits Solana Lints
# Cargo.toml に追加
[dependencies]
solana-program = "1.17" # 最新バージョンを使用
[lints.clippy]
# Solana 固有の lints を有効化
# (Trail of Bits solana-lints 利用可能な場合)
8. Reporting Format
Finding Template
## [CRITICAL] Arbitrary CPI - Unchecked Program ID
**Location**: `programs/vault/src/lib.rs:145-160` (withdraw function)
**Description**:
`withdraw` 関数は提供された `token_program` アカウントが実際に SPL Token プログラムであることを検証せずに、SPL トークンを転送するための CPI を実行します。攻撃者は転送を実行するように見えますが、実際にはトークンを盗むか不正な操作を実行する悪意あるプログラムを提供することができます。
**Vulnerable Code**:
```rust
// lib.rs, line 145
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
let token_program = &ctx.accounts.token_program;
// 間違い: token_program.key() の検証がない!
invoke(
&spl_token::instruction::transfer(...),
&[
ctx.accounts.vault.to_account_info(),
ctx.accounts.destination.to_account_info(),
ctx.accounts.authority.to_account_info(),
token_program.to_account_info(), // 検証なし
],
)?;
Ok(())
}
Attack Scenario:
- 攻撃者は転送命令をログしますが実行しない悪意あるプログラムをデプロイします
- 攻撃者は withdraw() を呼び出し、悪意あるプログラムを token_program として渡します
- Vault の権限がトランザクションに署名します
- 悪意あるプログラムが Vault の署名付き CPI を受け取ります
- 悪意あるプログラムは Vault になりすまして実トークンをドレインできます
Recommendation:
Anchor の Program<'info, Token> タイプを使用:
use anchor_spl::token::{Token, Transfer};
#[derive(Accounts)]
pub struct Withdraw<'info> {
#[account(mut)]
pub vault: Account<'info, TokenAccount>,
#[account(mut)]
pub destination: Account<'info, TokenAccount>,
pub authority: Signer<'info>,
pub token_program: Program<'info, Token>, // プログラム ID を自動的に検証
}
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
let cpi_accounts = Transfer {
from: ctx.accounts.vault.to_account_info(),
to: ctx.accounts.destination.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
};
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
cpi_accounts,
);
anchor_spl::token::transfer(cpi_ctx, amount)?;
Ok(())
}
References:
- building-secure-contracts/not-so-smart-contracts/solana/arbitrary_cpi
- Trail of Bits lint:
unchecked-cpi-program-id
---
## 9. Priority Guidelines
### Critical (Immediate Fix Required)
- Arbitrary CPI(攻撃者制御のプログラム実行)
- Improper PDA validation(アカウントスプーフィング)
- Missing signer check(不正アクセス)
### High (Fix Before Launch)
- Missing ownership check(偽アカウントデータ)
- Sysvar account check(認証バイパス、1.8.1 以前)
### Medium (Address in Audit)
- Improper instruction introspection(ロジックバイパス)
---
## 10. Testing Recommendations
### Unit Tests
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_rejects_wrong_program_id() {
// 間違ったプログラム ID を提供、失敗するべき
}
#[test]
#[should_panic]
fn test_rejects_non_canonical_pda() {
// 正規でない bump を提供、失敗するべき
}
#[test]
#[should_panic]
fn test_requires_signer() {
// 署名なしで呼び出し、失敗するべき
}
}
Integration Tests (Anchor)
import * as anchor from "@coral-xyz/anchor";
describe("security tests", () => {
it("rejects arbitrary CPI", async () => {
const fakeTokenProgram = anchor.web3.Keypair.generate();
try {
await program.methods
.withdraw(amount)
.accounts({
tokenProgram: fakeTokenProgram.publicKey, // 間違ったプログラム
})
.rpc();
assert.fail("Should have rejected fake program");
} catch (err) {
// 失敗が予期される
}
});
});
Solana Test Validator
# ローカル validator を実行
solana-test-validator
# プログラムをデプロイしてテスト
anchor test
11. Additional Resources
- Building Secure Contracts:
building-secure-contracts/not-so-smart-contracts/solana/ - Trail of Bits Solana Lints: https://github.com/trailofbits/solana-lints
- Anchor Documentation: https://www.anchor-lang.com/
- Solana Program Library: https://github.com/solana-labs/solana-program-library
- Solana Cookbook: https://solanacookbook.com/
12. Quick Reference Checklist
Solana プログラム監査を完了する前に:
CPI Security (CRITICAL):
- すべての CPI 呼び出しが
invoke()の前にプログラム ID を検証 - ユーザー提供のプログラムアカウントを使用できない
- Anchor:
Program<'info, T>タイプを使用
PDA Security (CRITICAL):
- PDA が
find_program_address()または Anchorseeds制約を使用 - Bump シードが保存および再利用される(ユーザー提供ではない)
- PDA アカウントが正規アドレスに対して検証される
Account Validation (HIGH):
- すべてのアカウントがデシリアライズ前に所有者をチェック
- ネイティブ:
account.owner == expected_program_idを検証 - Anchor:
Account<'info, T>タイプを使用
Signer Validation (CRITICAL):
- すべての権限アカウントが
is_signerをチェック - ネイティブ:
account.is_signer == trueを検証 - Anchor:
Signer<'info>タイプを使用
Sysvar Security (HIGH):
- Solana 1.8.1 以上を使用
- チェック済み関数を使用:
load_instruction_at_checked() - Sysvar アドレスが検証される
Instruction Introspection (MEDIUM):
- 関連付けに相対インデックスを使用
- 関連命令間での適切な検証
- 複数の呼び出しで同じ命令を再利用できない
Testing:
- すべてのアカウント検証をカバーするユニットテスト
- 悪意あるインプットを使用した統合テスト
- ローカル validator テストを完了
- Trail of Bits lints が有効化され成功
ライセンス: CC-BY-SA-4.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- trailofbits
- リポジトリ
- trailofbits/skills
- ライセンス
- CC-BY-SA-4.0
- 最終更新
- 不明
Source: https://github.com/trailofbits/skills / ライセンス: CC-BY-SA-4.0
関連スキル
superfluid
Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。