Skip to main content

05 - Type Confusion

Analysis

Type confusion occurs when a program interprets an account of one type as if it were another. In Solana, this usually happens when a program accepts two different account types with similar memory layouts but different roles (e.g., User vs. Admin).

Without a Discriminator (a unique prefix identifying the type), an attacker can pass a User account into an instruction expecting an Admin account, potentially gaining unauthorized privileges.

Exploit (Insecure)

Using UncheckedAccount and manually deserializing without checking a discriminator:

pub fn admin_action_insecure(ctx: Context<AdminActionInsecure>) -> Result<()> {
// No check to ensure 'admin' isn't actually a 'user' account.
msg!("Privileged action by: {}", ctx.accounts.admin.key());
Ok(())
}

Fix (Secure)

The standard solution is to prepend an 8-byte discriminator to every account. Anchor does this by default for any struct marked with #[account].

pub fn admin_action_secure(ctx: Context<AdminActionSecure>) -> Result<()> {
// Anchor checks the 8-byte discriminator automatically.
msg!("Privileged action by: {}", ctx.accounts.admin.authority);
Ok(())
}