Skip to main content
Sigvex

SPL Token ATA Validation Remediation

How to fix improper Associated Token Account validation.

SPL Token ATA Validation Remediation

Overview

Related Detector: SPL Token ATA Validation

Missing ATA derivation validation allows attackers to substitute arbitrary token accounts in place of the canonical Associated Token Account. The fix verifies that token account addresses match the expected ATA derivation.

Before (Vulnerable)

// Accepts any token account without ATA check
let dest = &accounts[1];
spl_token::instruction::transfer(..., dest.key, ...)?;

After (Fixed)

let dest = &accounts[1];
let user = &accounts[3];
let mint = &accounts[4];

let expected_ata = get_associated_token_address(user.key, mint.key);
if dest.key != &expected_ata {
    return Err(ProgramError::InvalidAccountData);
}

spl_token::instruction::transfer(..., dest.key, ...)?;

Alternative Mitigations

1. Anchor associated_token constraint

#[derive(Accounts)]
pub struct Transfer<'info> {
    #[account(
        mut,
        associated_token::mint = mint,
        associated_token::authority = user
    )]
    pub user_token: Account<'info, TokenAccount>,
    pub user: SystemAccount<'info>,
    pub mint: Account<'info, Mint>,
}

2. Init-if-needed ATA creation

#[account(
    init_if_needed,
    payer = payer,
    associated_token::mint = mint,
    associated_token::authority = user
)]
pub user_token: Account<'info, TokenAccount>,

Common Mistakes

Mistake 1: Deriving ATA with wrong mint

// WRONG: using a different mint for derivation
let ata = get_associated_token_address(user.key, &wrong_mint);

Mistake 2: Not creating ATA before transferring

// WRONG: transferring to non-existent ATA causes failure
// Use init_if_needed or create_associated_token_account first

References