| name | solana-security-standard |
| description | Use the SOL-0XX Solana security standard to scan, detect, and prevent 37 classes of Solana program vulnerabilities ($514M+ in real exploits) across AI tools, editors, CLI, and CI |
| triggers | ["scan my Solana program for security issues","check this Anchor code against SOL-0XX rules","run solana security standard on my programs","integrate solana security checks into my project","what SOL-0XX rules apply to this code","set up solana security scanning in CI","validate this solana program against the security standard","detect solana vulnerabilities in my codebase"] |
solana-security-standard
Skill by ara.so — Security Skills collection.
The Solana Security Standard provides 37 SOL-0XX rules distilled from $514M+ of real Solana exploits. It catches caller-controlled clock values, cross-market state asymmetry, missing Anchor constraints, wrapper/engine drift, and 33 other bug classes — firing as you code in AI tools, editors, CLI, and CI.
SOL-001 alone covers 2 confirmed bounty wins (caller-controlled now_slot in percolator). The standard works across Claude Code, Cursor, Windsurf, Copilot, Cline, Aider, the VS Code extension, the CLI, Semgrep, GitHub Actions, and any MCP client.
Installation
Claude Code (quickest)
mkdir -p .claude && \
curl -sL https://raw.githubusercontent.com/Copenhagen0x/solana-security-standard/main/plugin-guidance.md \
-o .claude/claude-security-guidance.md && \
curl -sL https://raw.githubusercontent.com/Copenhagen0x/solana-security-standard/main/security-patterns.yaml \
-o .claude/security-patterns.yaml
Then install the security-guidance plugin:
/plugin install security-guidance@claude-plugins-official
/reload-plugins
Or install the full MCP-powered plugin:
/plugin marketplace add Copenhagen0x/solana-security-standard
/plugin install solana-security-standard@solana-security-standard
CLI (any machine)
npx @jelleo/solana-security-standard scan ./programs
No install needed — runs via npx. Zero dependencies.
CI — GitHub Action
name: Solana Security Standard
on: [pull_request]
permissions:
contents: read
security-events: write
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: Copenhagen0x/solana-security-standard@v1
with:
paths: ./programs
fail-on-findings: true
upload-sarif: true
VS Code / Cursor / Windsurf
Install from Open VSX:
- Cursor / Windsurf / VSCodium: Search "Solana Security Standard" in Extensions
- VS Code: Sideload
.vsix from extensions/vscode/
Shows inline warnings as you type in Rust and TypeScript/JS files.
MCP (any MCP client)
Add to your MCP settings (.cline/mcp.json, .cursor/mcp.json, etc.):
{
"mcpServers": {
"solana-security-standard": {
"command": "npx",
"args": ["-y", "@jelleo/solana-security-mcp"]
}
}
}
Exposes scan_solana_code tool + list_solana_security_rules resource.
AI Agents (Codex, Copilot, Cursor, Windsurf, Cline, Aider)
Copy the rules file for your tool:
| Tool | Copy into repo |
|---|
| Codex / AGENTS.md | integrations/codex/AGENTS.md |
| GitHub Copilot | integrations/copilot/.github/copilot-instructions.md |
| Cursor | integrations/cursor/.cursor/ |
| Windsurf | integrations/windsurf/.windsurf/ |
| Cline | integrations/cline/.clinerules |
| Aider | integrations/aider/ |
curl -sL https://raw.githubusercontent.com/Copenhagen0x/solana-security-standard/main/integrations/cursor/.cursor/rules -o .cursor/rules
Semgrep
semgrep --config https://raw.githubusercontent.com/Copenhagen0x/solana-security-standard/main/semgrep/solana-security-standard.yaml ./programs
CLI Commands
Scan programs
npx @jelleo/solana-security-standard scan ./programs
npx @jelleo/solana-security-standard scan ./programs/src/lib.rs
npx @jelleo/solana-security-standard scan ./programs --format json
npx @jelleo/solana-security-standard scan ./programs --format sarif > results.sarif
npx @jelleo/solana-security-standard scan ./programs --min-tier high
npx @jelleo/solana-security-standard scan ./programs --baseline .sss-baseline.json
Generate baseline
npx @jelleo/solana-security-standard scan ./programs --format json > .sss-baseline.json
npx @jelleo/solana-security-standard scan ./programs --baseline .sss-baseline.json
CLI exits non-zero on findings (gates CI).
Key Rules (37 total)
Critical On-Chain Rules
| Rule | Bug Class | Example |
|---|
| SOL-001 | Unauthenticated now_slot / clock spoofing | 2 confirmed bounty wins |
| SOL-002 | Cross-market state asymmetry | Counter inflation |
| SOL-003 | Wrapper re-implements engine logic | Drift from canonical |
| SOL-004 | Missing signer check | Unauthorized access |
| SOL-005 | Missing owner check | Wrong program control |
| SOL-006 | Account data type confusion | Misinterpreted structs |
| SOL-007 | Uninitialized account | Reading zeroed data |
| SOL-008 | Arithmetic overflow/underflow | Balance manipulation |
| SOL-009 | PDA derivation mismatch | Wrong seeds → wrong account |
| SOL-010 | Missing rent exemption | Account closure drain |
Integrator / Client-Side Rules
| Rule | Bug Class |
|---|
| SOL-029 | Client-side arithmetic overflow (TypeScript/JS) |
| SOL-030 | Missing transaction simulation |
| SOL-031 | Hardcoded program IDs in client |
Full list: https://github.com/Copenhagen0x/solana-security-standard/blob/main/claude-security-guidance.md
Real Code Examples
SOL-001: Unauthenticated now_slot (2 bounty wins)
Vulnerable (percolator-prog ACTIVATE):
pub fn activate(ctx: Context<Activate>, now_slot: u64) -> Result<()> {
let state = &mut ctx.accounts.state;
let clock = Clock::get()?;
if now_slot < state.cooldown_end {
return Err(ErrorCode::CooldownActive.into());
}
state.active = true;
Ok(())
}
Fixed:
pub fn activate(ctx: Context<Activate>) -> Result<()> {
let state = &mut ctx.accounts.state;
let clock = Clock::get()?;
if clock.slot < state.cooldown_end {
return Err(ErrorCode::CooldownActive.into());
}
state.active = true;
Ok(())
}
SOL-004: Missing signer check
Vulnerable:
#[derive(Accounts)]
pub struct Withdraw<'info> {
#[account(mut)]
pub authority: AccountInfo<'info>,
#[account(mut)]
pub vault: Account<'info, Vault>,
}
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
transfer_from_vault(&ctx.accounts.vault, amount)?;
Ok(())
}
Fixed:
#[derive(Accounts)]
pub struct Withdraw<'info> {
#[account(mut)]
pub authority: Signer<'info>,
#[account(
mut,
has_one = authority // Links vault to this authority
)]
pub vault: Account<'info, Vault>,
}
SOL-009: PDA derivation mismatch
Vulnerable:
let (vault_pda, _bump) = Pubkey::find_program_address(
&[b"vault", user.key().as_ref()],
program_id
);
if vault_pda != *vault.key {
return Err(ErrorCode::InvalidVault.into());
}
Fixed:
let (vault_pda, _bump) = Pubkey::find_program_address(
&[b"vault", market_id.as_ref(), user.key().as_ref()],
program_id
);
if vault_pda != *vault.key {
return Err(ErrorCode::InvalidVault.into());
}
SOL-029: Client-side arithmetic overflow (TypeScript)
Vulnerable:
const depositAmount = userBalance + newDeposit;
const tx = await program.methods
.deposit(new BN(depositAmount))
.accounts({ vault, user })
.rpc();
Fixed:
import { BN } from "@coral-xyz/anchor";
const depositAmount = new BN(userBalance).add(new BN(newDeposit));
const tx = await program.methods
.deposit(depositAmount)
.accounts({ vault, user })
.rpc();
Configuration
GitHub Action Options
- uses: Copenhagen0x/solana-security-standard@v1
with:
paths: ./programs
fail-on-findings: true
upload-sarif: true
min-tier: high
baseline: .sss-baseline.json
VS Code Extension Settings
{
"solanaSecurityStandard.minTier": "medium",
"solanaSecurityStandard.excludePatterns": [
"**/tests/**",
"**/target/**"
]
}
Semgrep Integration
semgrep --config ./my-sss-rules.yaml ./programs
semgrep --config auto --config ./semgrep/solana-security-standard.yaml ./programs
Common Patterns
Pre-commit Hook
npx @jelleo/solana-security-standard scan programs/ --min-tier high
if [ $? -ne 0 ]; then
echo "❌ Solana security scan failed — fix findings or commit with --no-verify"
exit 1
fi
chmod +x .git/hooks/pre-commit
Baseline Workflow (gate on regressions only)
npx @jelleo/solana-security-standard scan ./programs --format json > .sss-baseline.json
git add .sss-baseline.json
git commit -m "chore: add security baseline"
npx @jelleo/solana-security-standard scan ./programs --baseline .sss-baseline.json
Only new findings fail the build.
Multi-repo Monorepo Scan
npx @jelleo/solana-security-standard scan \
./packages/protocol/programs \
./packages/staking/programs \
./packages/governance/programs
Filter by Rule
CLI doesn't support per-rule filtering, but you can grep JSON output:
npx @jelleo/solana-security-standard scan ./programs --format json \
| jq '.findings[] | select(.rule == "SOL-001")'
MCP Tools
When installed as MCP server:
scan_solana_code
{
"code": "pub fn transfer(ctx: Context<Transfer>, amount: u64) -> Result<()> { ... }",
"language": "rust"
}
list_solana_security_rules
Troubleshooting
"Module not found" in CLI
rm -rf ~/.npm/_npx
npx @jelleo/solana-security-standard scan ./programs
VS Code extension not activating
- Check output panel: View → Output → "Solana Security Standard"
- Verify file is
.rs, .ts, or .js
- Reload window: Cmd/Ctrl+Shift+P → "Reload Window"
False positives
pub authority: AccountInfo<'info>,
pub authority: AccountInfo<'info>,
pub authority: UncheckedAccount<'info>,
GitHub Action fails with SARIF error
permissions:
contents: read
security-events: write
Baseline not filtering findings
Baseline only gates new findings. If you want to suppress known findings:
npx @jelleo/solana-security-standard scan ./programs --format json > .sss-baseline.json
Real Exploit Mappings
Every rule links to real disclosed exploits:
- SOL-001: Wormhole ($325M), percolator bounties
- SOL-008: Mango Markets ($114M)
- SOL-010: Cashio ($52M)
- SOL-017: Crema Finance ($8.8M)
See hacks/README.md for full database.
Badge for Your README
Show adoption:
[](https://github.com/Copenhagen0x/solana-security-standard)
Resources