◂ labs
TIER 1 · THE ACCOUNT MODEL · 1-account-data-matching
ACCOUNT DATA MATCHING
An account that is structurally right but semantically wrong: the type checks out, the data inside belongs to someone else. Without checking a stored field (e.g. `account.authority == signer.key`), the program trusts whatever was passed.
seen in the wild
Variant of the Cashio infinite-mint: an unvalidated collateral account let the attacker mint $52M of CASH.
rust · anchor
use anchor_lang::prelude::*;
use anchor_lang::solana_program::program_pack::Pack;
use spl_token::state::Account as SplTokenAccount;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod account_data_matching_insecure {
use super::*;
pub fn log_message(ctx: Context<LogMessage>) -> ProgramResult {
let token = SplTokenAccount::unpack(&ctx.accounts.token.data.borrow())?;
msg!("Your account balance is: {}", token.amount);
Ok(())
}
}
#[derive(Accounts)]
pub struct LogMessage<'info> {
token: AccountInfo<'info>,
authority: Signer<'info>,
}
next labOWNER CHECKS ▸