Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛡️ SolSec Workshop: Solana Security Vulnerability Lab

A comprehensive, hands-on educational resource demonstrating common Solana/Anchor security vulnerabilities and their mitigations.

Solana Anchor License Vulnerabilities CTF Challenges


📋 Overview

SolSec Workshop is an interactive security education platform that teaches developers how to identify, exploit, and fix common vulnerabilities in Solana programs. Each module contains:

  • 🔴 Vulnerable code with intentional security flaws
  • 🟢 Secure code demonstrating proper mitigations
  • 📝 Comprehensive tests that explain attack vectors
  • 📚 Deep-dive documentation for thorough understanding
  • 🏆 CTF challenges to practice your skills

🎯 Target Audience

  • Smart contract developers new to Solana
  • Auditors learning Solana-specific vulnerabilities
  • Security researchers exploring the ecosystem
  • Teams building secure DeFi protocols

💀 Hall of Hacks: Real-World Exploits

Learn from history - these vulnerabilities have cost the ecosystem hundreds of millions.

Protocol Loss Vulnerability Our Module
Wormhole $320M Signature verification bypass Signer Authorization
Cashio $50M Infinite mint via reinit Reinitialization
Mango Markets $114M Oracle manipulation Account Data Matching
Slope Wallet $8M Key exposure Owner Check
Crema Finance $8.8M Flash loan + oracle Integer Overflow

🗂️ Vulnerability Modules

# Vulnerability Impact Difficulty Real Exploits
1 Signer Authorization 🔴 Critical 🟢 Beginner Wormhole
2 Owner Check 🟠 High 🟢 Beginner Multiple
3 Account Data Matching 🟠 High 🟡 Intermediate Mango
4 Type Cosplay 🔴 Critical 🟡 Intermediate Saber
5 Arbitrary CPI 🔴 Critical 🔴 Advanced Multiple DeFi
6 Integer Overflow 🔴 Critical 🟡 Intermediate Crema
7 Reinitialization 🔴 Critical 🟡 Intermediate Cashio
8 PDA Seed Collision 🟠 High 🟡 Intermediate Various
9 Closing Accounts 🟠 High 🟡 Intermediate Various

🔀 Attack Flow Diagrams

Signer Authorization Attack

sequenceDiagram
    participant Attacker
    participant Program
    participant Vault
    
    Note over Attacker,Vault: Vulnerable: AccountInfo instead of Signer
    
    Attacker->>Program: withdraw(victim_pubkey, amount)
    Note right of Attacker: Passes pubkey without signing
    Program->>Program: ❌ No signature check!
    Program->>Vault: Transfer funds
    Vault-->>Attacker: 💰 Funds stolen
Loading

Reinitialization Attack

sequenceDiagram
    participant Protocol
    participant Attacker
    participant Config
    
    Protocol->>Config: initialize(admin=PROTOCOL)
    Note over Config: Admin set to protocol
    
    Attacker->>Config: initialize(admin=ATTACKER)
    Note over Config: ❌ No init check!
    Note over Config: Admin overwritten!
    
    Attacker->>Config: withdraw_treasury()
    Config-->>Attacker: 💰 All funds
Loading

Type Cosplay Attack

graph LR
    A[Attacker Account<br/>Discriminator: User] -->|Passed as| B[Program]
    C[Victim Account<br/>Discriminator: User] -->|Also valid| B
    B -->|Same bytes, different meaning| D[❌ Wrong interpretation]
    D --> E[💰 Funds stolen]
Loading

1. Signer Authorization

Location: programs/signer-authorization/

The Vulnerability

Missing or improper verification that an account has actually signed the transaction.

// ❌ INSECURE: No signer verification
pub authority: AccountInfo<'info>,

// ✅ SECURE: Anchor enforces signature
pub authority: Signer<'info>,

Real-World Case: Wormhole ($320M)

The attacker bypassed signature verification on the guardian set, allowing them to mint wrapped ETH without valid signatures from the bridge guardians.

Prevention

  • Use Signer<'info> for all authority accounts
  • Add #[account(signer)] constraint when using AccountInfo
  • Manually check authority.is_signer

2. Owner Check

Location: programs/owner-check/

The Vulnerability

Failing to verify that an account is owned by the expected program.

// ❌ INSECURE: Accepts any account
pub token_account: AccountInfo<'info>,

// ✅ SECURE: Verifies Token Program ownership  
pub token_account: Account<'info, TokenAccount>,

Prevention

  • Use Anchor's Account<'info, T> wrapper
  • Manually verify with constraint = account.owner == expected_program.key()
  • Never trust raw AccountInfo for data

3. Account Data Matching

Location: programs/account-data-matching/

The Vulnerability

Not validating that account relationships match expected constraints.

// ❌ INSECURE: No relationship verification
pub vault: Account<'info, Vault>,
pub authority: AccountInfo<'info>,

// ✅ SECURE: Enforces data matching
#[account(has_one = authority)]
pub vault: Account<'info, Vault>,
pub authority: Signer<'info>,

Prevention

  • Use has_one constraint for all account relationships
  • Add explicit constraint checks when needed
  • Verify account derivation with seeds

4. Type Cosplay

Location: programs/type-cosplay/

The Vulnerability

Different account types with identical data layouts can be confused.

// ❌ INSECURE: Manual deserialization without type checking
let data = User::try_from_slice(&account.data.borrow())?;

// ✅ SECURE: Anchor's discriminator prevents confusion
#[account]
pub struct User { ... }  // Anchor adds 8-byte discriminator

Prevention

  • Always use #[account] for Anchor discriminators
  • Use Account<'info, T> instead of raw AccountInfo
  • Add explicit type validation for dynamic account handling

5. Arbitrary CPI

Location: programs/arbitrary-cpi/

The Vulnerability

Allowing arbitrary programs to be invoked without verification.

// ❌ INSECURE: Any program accepted
pub token_program: AccountInfo<'info>,

// ✅ SECURE: Only Token Program allowed
pub token_program: Program<'info, Token>,

Prevention

  • Use Program<'info, T> with interface constraints
  • Whitelist allowed programs by ID
  • Verify program IDs before CPI

6. Integer Overflow

Location: programs/integer-overflow/

The Vulnerability

Arithmetic operations that exceed type bounds cause unexpected behavior.

// ❌ INSECURE: Can underflow
vault.balance = vault.balance - amount;

// ✅ SECURE: Returns error on underflow
vault.balance = vault.balance
    .checked_sub(amount)
    .ok_or(ErrorCode::Underflow)?;

Prevention

  • Use checked_* methods for all arithmetic
  • Upcast to u128 for intermediate multiplication
  • Enable overflow-checks = true in release profile

7. Reinitialization Attack

Location: programs/reinitialization/

The Vulnerability

Allowing initialization functions to be called multiple times.

// ❌ INSECURE: Can be called multiple times
#[account(mut)]
pub config: Account<'info, Config>,

// ✅ SECURE: Anchor's init ensures first-time only
#[account(init, payer = admin, space = 8 + Config::INIT_SPACE)]
pub config: Account<'info, Config>,

Real-World Case: Cashio ($50M)

Attackers reinitialized the collateral account to mint infinite CASH tokens, crashing the stablecoin to zero.

Prevention

  • Always use Anchor's init constraint
  • Or check is_initialized flag BEFORE any state changes
  • Use two-step admin transfer pattern

8. PDA Seed Collision

Location: programs/pda-seed-collision/

The Vulnerability

Poorly designed PDA seeds cause different logical entities to derive the same address.

// ❌ INSECURE: Missing unique identifier
seeds = [b"vault", user.key().as_ref()]  // All tokens same PDA!

// ✅ SECURE: Include all unique identifiers
seeds = [b"vault", user.key().as_ref(), token_mint.key().as_ref()]

Attack Vectors

  • String concatenation collision: "AB" + "C" == "A" + "BC"
  • Sequential IDs enable front-running
  • Missing identifiers cause overwrites

Prevention

  • Include ALL unique identifiers in seeds
  • Use fixed-size pubkeys instead of strings
  • Add random nonce for unpredictable PDAs
  • Canonical ordering for symmetric relationships

9. Closing Accounts

Location: programs/closing-accounts/

The Vulnerability

Improper account closing leads to fund loss or revival attacks.

// ❌ INSECURE: Manual close without zeroing
**vault.lamports.borrow_mut() = 0;  // Data still readable!

// ✅ SECURE: Anchor's close zeros data
#[account(mut, close = authority)]
pub vault: Account<'info, Vault>,

Attack Vectors

  • Rent Extraction: Drain lamports, account persists briefly
  • Revival Attack: Refund lamports in same transaction
  • Force Defund: Anyone closes unprotected accounts

Prevention

  • Always use Anchor's close constraint
  • Check balance == 0 before closing
  • Track closure timestamp for revival detection

🏆 CTF Challenges

Test your skills with our Capture The Flag challenges!

challenges/
├── challenge-1-insecure-vault/    🟢 Easy     (100 pts)
├── challenge-2-token-drain/       🟡 Medium   (250 pts)  
├── challenge-3-admin-takeover/    🟡 Medium   (250 pts)
├── challenge-4-flash-loan/        🔴 Hard     (500 pts)
└── challenge-5-oracle/            🔴 Hard     (500 pts)

See challenges/README.md for rules and instructions.


🚀 Getting Started

Prerequisites

Installation

# Clone the repository
git clone https://github.com/YOUR_USERNAME/solsec-workshop.git
cd solsec-workshop

# Install dependencies
npm install

# Build programs
anchor build

# Run tests
anchor test

Running Individual Tests

# Run specific vulnerability test
anchor test -- --grep "Signer Authorization"

# Run with verbose output  
anchor test -- --reporter spec

📁 Project Structure

solsec-workshop/
├── programs/                       # Vulnerable + secure programs
│   ├── signer-authorization/
│   ├── owner-check/
│   ├── account-data-matching/
│   ├── type-cosplay/
│   ├── arbitrary-cpi/
│   ├── integer-overflow/
│   ├── reinitialization/          # NEW
│   ├── pda-seed-collision/        # NEW
│   └── closing-accounts/          # NEW
├── tests/                          # Educational test suites
├── challenges/                     # CTF challenges
├── docs/
│   ├── DEEP_DIVE.md               # Comprehensive analysis
│   └── AUDIT_CHECKLIST.md         # Professional audit checklist
├── Anchor.toml
└── README.md

📋 Security Audit Checklist

We provide a comprehensive audit checklist covering:

  • ✅ Account Validation (Signer, Owner, Relationships)
  • ✅ PDA Security (Seeds, Collisions)
  • ✅ Arithmetic Safety (Overflow, Precision)
  • ✅ Access Control (Init, Admin, Roles)
  • ✅ CPI Security (Program verification)
  • ✅ Account Lifecycle (Closing, Revival)
  • ✅ Token Security (Transfers, Validation)
  • ✅ Economic Security (Oracles, Flash Loans)

🛠️ Additional Resources

Official Documentation

Security References


🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add your vulnerability example with tests
  4. Submit a pull request

⚠️ Disclaimer

This repository contains intentionally vulnerable code for educational purposes only. DO NOT deploy any insecure code to mainnet. The vulnerabilities demonstrated here have been exploited in real-world attacks causing hundreds of millions in losses.


📄 License

MIT License - See LICENSE for details.


Built with ❤️ for the Solana security community

VulnerabilitiesCTF ChallengesAudit ChecklistDeep Dive

About

Solana Security Vulnerability Lab: A comprehensive, hands-on educational resource demonstrating common Solana/Anchor security vulnerabilities and their mitigations.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages