Native Discriminator Validation Remediation
Overview
Related Detector: Native Discriminator Validation
Missing account type discriminators enable type confusion. The fix is to prepend a unique discriminator byte (or bytes) to every account type and validate it before deserialization.
Impact. Without a discriminator to distinguish account types, a program handed one type where another is expected deserializes it as though it were legitimate (type cosplay). An attacker crafts an account whose bytes line up with the target layout and slips it past validation, so authority or balance fields are read from attacker-controlled data — a direct route to privilege escalation or theft.
Recommended Fix
Before (Vulnerable)
let vault: VaultState = VaultState::try_from_slice(&data)?;
After (Fixed)
const VAULT_TAG: u8 = 1;
const USER_TAG: u8 = 2;
require!(data[0] == VAULT_TAG, InvalidAccountType);
let vault: VaultState = VaultState::try_from_slice(&data[1..])?;
Alternative Mitigations
SHA256-Based Discriminators
For stronger type safety, use 8-byte SHA256 discriminators similar to Anchor:
use solana_program::hash::hash;
let expected = &hash(b"account:VaultState").to_bytes()[..8];
require!(&data[..8] == expected, InvalidAccountType);
Common Mistakes
Mistake: Same Discriminator for Different Types
// WRONG: both account types use discriminator 1
const VAULT_TAG: u8 = 1;
const USER_TAG: u8 = 1; // Collision!
Use unique discriminator values for every account type.