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.
Recommended Fix
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 Anchor’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.