Account List Size Remediation
How to fix missing account list size validation for fixed account layouts.
Account List Size Remediation
Overview
Related Detector: Account List Size
Programs that access multiple accounts at fixed indices without validating the total count will panic when fewer accounts are provided than expected. The fix is a single length check at the top of the instruction handler that verifies the minimum required number of accounts.
Recommended Fix
Before (Vulnerable)
pub fn process(accounts: &[AccountInfo]) -> ProgramResult {
let user = &accounts[0];
let vault = &accounts[1];
let token_program = &accounts[2];
// Panics if < 3 accounts
Ok(())
}
After (Fixed)
pub fn process(accounts: &[AccountInfo]) -> ProgramResult {
if accounts.len() < 3 {
return Err(ProgramError::NotEnoughAccountKeys);
}
let user = &accounts[0];
let vault = &accounts[1];
let token_program = &accounts[2];
Ok(())
}
Alternative Mitigations
Use Anchor’s #[derive(Accounts)] to declare all required accounts. Anchor validates the exact count automatically:
#[derive(Accounts)]
pub struct Process<'info> {
pub user: Signer<'info>,
#[account(mut)]
pub vault: Account<'info, Vault>,
pub token_program: Program<'info, Token>,
}
Use next_account_info for sequential, safe account consumption in native programs:
let iter = &mut accounts.iter();
let user = next_account_info(iter)?;
let vault = next_account_info(iter)?;
let token_program = next_account_info(iter)?;
Common Mistakes
Checking for fewer accounts than actually used. If the function accesses accounts[4], the check must be accounts.len() >= 5, not >= 4.
Adding the check after the first account access. The check must precede all index-based access to be effective.
Not updating the check when adding new accounts. When a new account is added to the layout, the length constant must increase accordingly. Use a named constant (const EXPECTED: usize = 5) to make updates explicit.