Skip to content

Rule: Taint user-controlled seed bytes without guard constraint #5

@Cass402

Description

@Cass402

Summary

Flag PDA derivations where any seed is derived from untrusted user input without a constraint or validation.
Related to #3

Why it matters

If a PDA’s seed includes unchecked user-controlled data, the PDA address can be redirected to attacker-controlled accounts. This is a common source of logic bypasses and fund loss.

Proposed Approach

•	Taint IX arguments and account fields that are not proven equal to trusted state.
•	If a tainted value flows into seeds=[...] without a guard pattern (e.g., require!(arg == state.allowed), has_one = arg, custom validate), raise a finding.

Examples

Flag:

#[account(seeds=[b"pos", user_input.as_ref()], bump)]
pub position: Account<'info, Position>;

(no validation)

Pass:

#[account(seeds=[b"pos", user_input.as_ref()], bump, has_one = user_input)]
pub position: Account<'info, Position>;

(or require!(user_input == state.owner))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions