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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions