Skip to main content
Sigvex

PDA Seed Collision

Detects PDA derivations with weak seed patterns that could collide with other PDAs or system addresses, enabling account hijacking.

PDA Seed Collision

Overview

The PDA seed collision detector identifies Program Derived Address (PDA) derivations that use weak or predictable seed combinations, making it possible for an attacker to derive the same PDA with different semantic meaning, or to find collisions with PDAs from other programs. If two PDAs collide, the attacker who controls one can manipulate the other’s state.

Why This Is an Issue

PDAs serve as program-owned accounts with deterministic addresses. If a program uses only a single short seed (e.g., [b"vault"]) without user-specific or program-specific components, multiple users share the same PDA. If seeds lack a program namespace prefix, another program could derive the same PDA and claim ownership of the account.

How to Resolve

// Before: Vulnerable — single shared seed, no namespace
let (pda, bump) = Pubkey::find_program_address(&[b"vault"], program_id);

// After: Fixed — user-specific seed with program namespace
let (pda, bump) = Pubkey::find_program_address(
    &[b"vault", user_pubkey.as_ref()],
    program_id,
);

Detection Methodology

  1. PDA derivation identification: Locates find_program_address and create_program_address calls.
  2. Seed entropy analysis: Evaluates the number and diversity of seeds — single-seed or short constant-only derivations receive higher risk scores.
  3. Namespace check: Verifies whether seeds include program-specific prefixes to prevent cross-program collisions.
  4. User-specific seed check: Determines whether user pubkeys or unique identifiers are included in the seed set.

Limitations

False positives: Programs that intentionally use singleton PDAs (one per program) may be flagged. False negatives: Collisions caused by truncated seed values (seeds longer than 32 bytes are hashed) may not be detected.

References