Skip to main content
Sigvex

Account Index Bounds Remediation

How to fix account array access without bounds validation.

Account Index Bounds Remediation

Overview

Related Detector: Account Index Bounds

Accessing accounts by index without bounds checking causes runtime panics when the index exceeds the array length. The fix is to validate the index before use, or use safe accessor methods that return Option or Result on out-of-bounds access.

Before (Vulnerable)

pub fn process(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
    let idx = data[0] as usize;
    let target = &accounts[idx]; // Panics if idx >= accounts.len()
    transfer_to(target, 1000)
}

After (Fixed)

pub fn process(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
    let idx = data[0] as usize;
    let target = accounts.get(idx)
        .ok_or(ProgramError::NotEnoughAccountKeys)?;
    transfer_to(target, 1000)
}

Alternative Mitigations

Use the account-validation framework’s #[derive(Accounts)] to declare expected accounts as named fields. Anchor validates the account count at deserialization time:

#[derive(Accounts)]
pub struct Transfer<'info> {
    #[account(mut)]
    pub source: Account<'info, TokenAccount>,
    #[account(mut)]
    pub destination: Account<'info, TokenAccount>,
    pub authority: Signer<'info>,
    // Anchor ensures exactly 3 accounts are provided
}

Use next_account_info iterator for native programs to safely consume accounts one at a time:

let account_iter = &mut accounts.iter();
let source = next_account_info(account_iter)?;
let destination = next_account_info(account_iter)?;
let authority = next_account_info(account_iter)?;
// Returns NotEnoughAccountKeys if too few accounts

Common Mistakes

Checking bounds for some indices but not all. If a function accesses accounts at indices 0, 1, and 2, all three must be validated. A single accounts.len() >= 3 check at the top covers all of them.

Using unwrap() on accounts.get(). This defeats the purpose of using the safe accessor. Always use ok_or or pattern matching.

Validating the index against a hardcoded maximum instead of accounts.len(). The actual array length is the only reliable upper bound.

References