Skip to main content
Learn about common security vulnerabilities in Solana programs and how Anchor helps prevent them.

Missing signer checks

Vulnerability: Not verifying that an account signed the transaction. Anchor protection: Use Signer<'info> type.
// Secure
#[derive(Accounts)]
pub struct Update<'info> {
    pub authority: Signer<'info>,  // Automatically checked
}

Missing ownership checks

Vulnerability: Not verifying account ownership. Anchor protection: Account<'info, T> automatically checks owner.
// Secure - owner checked automatically
#[account(mut)]
pub data: Account<'info, MyData>

Missing account validation

Vulnerability: Not validating account relationships. Anchor protection: Use has_one and constraint.
// Secure
#[account(
    mut,
    has_one = authority,
    constraint = data.count < MAX_COUNT
)]
pub data: Account<'info, MyData>

Arithmetic overflow/underflow

Vulnerability: Integer overflow causing unexpected behavior. Anchor protection: Use checked arithmetic.
// Vulnerable
counter.count = counter.count + amount;

// Secure
counter.count = counter.count.checked_add(amount)
    .ok_or(ErrorCode::Overflow)?;

Reinitialization attacks

Vulnerability: Allowing accounts to be reinitialized. Anchor protection: init constraint prevents reinitialization.
// Secure
#[account(init, payer = user, space = 8 + 8)]
pub data: Account<'info, Data>

PDA validation

Vulnerability: Not validating PDA derivation. Anchor protection: Use seeds and bump constraints.
// Secure
#[account(
    seeds = [b"vault", user.key().as_ref()],
    bump
)]
pub vault: Account<'info, Vault>

Account closing vulnerabilities

Vulnerability: Not properly closing accounts or returning lamports to wrong address. Anchor protection: Use close constraint.
// Secure
#[account(mut, close = authority)]
pub data: Account<'info, Data>

Duplicate mutable accounts

Vulnerability: Same account passed multiple times as mutable. Anchor protection: Anchor prevents duplicate mutable accounts by default (0.32+).
// If intentional, use dup constraint
#[account(mut, dup)]
pub account1: Account<'info, Data>,
#[account(mut)]
pub account2: Account<'info, Data>,

Type confusion

Vulnerability: Treating one account type as another. Anchor protection: Account discriminators prevent this.
// Each account type has unique 8-byte discriminator
#[account]
pub struct TypeA { }

#[account]
pub struct TypeB { }
// Cannot deserialize TypeA as TypeB

Best practices checklist

Before deploying:
  • All signers use Signer<'info> type
  • All accounts use appropriate Anchor types
  • All account relationships validated with has_one
  • All custom logic uses constraint
  • Arithmetic uses checked operations
  • PDAs use seeds and bump constraints
  • Account closes use close constraint
  • No UncheckedAccount without /// CHECK: comment
  • All error cases handled
  • Tests cover security scenarios

Security audits

For production programs:
  1. Self-audit using this checklist
  2. Peer review with experienced Solana developers
  3. Professional audit from security firms like:
    • OtterSec
    • Sec3
    • Neodyme
    • Trail of Bits

Learn more

Sealevel attacks

Common Solana vulnerabilities

Security guide

Anchor security patterns

Build docs developers (and LLMs) love