Rust Fund

AI First Flight #9
Beginner FriendlyRust
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Missing PDA seed constraint on fund account in FundContribute allows arbitrary account injection

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

// Root cause in the codebase with @> marks to highlight the relevant # Finding 2: contribute() has no PDA seed validation on fund account
**Severity:** Medium
**Title:** Missing PDA seed constraint on fund account in FundContribute allows arbitrary account injection
## Description
The `FundContribute` accounts struct (`lib.rs:119-134`) declares the `fund` account using only the `#[account(mut)]` attribute. It completely lacks `seeds`, `bump`, or `has_one` constraints. Because the `contribute` instruction does not validate that the passed account is the legitimate PDA derived from the correct seeds, any attacker can pass an arbitrary, attacker-controlled account into the instruction.
## Impact
An attacker can perform a phishing attack by passing a malicious look-alike account address into the transaction. When victims sign and execute `contribute()`, their SOL is directed via the internal CPI transfer to the attacker's account rather than the intended campaign contract.
## Proof of Concept
This execution step explains how an attacker passes a rogue account destination to intercept contributor funds:
1. Attacker deploys a look-alike account or malicious address (Fund B).
2. The attacker tricks a contributor into executing a transaction intended for the legitimate campaign (Fund A), but passes the address of Fund B instead.
3. The contract processes the instruction and transfers the contributor's SOL straight to the attacker's address because no seed verification is executed.
```rust
// Attacker triggers the contribution using a rogue fund address
contribute(
fund = attacker_controlled_address,
contributor = victim_signer,
amount = 10 * LAMPORTS_PER_SOL
)
// The CPI transfer triggers successfully, routing the 10 SOL directly to the attacker.
```
## Recommended Mitigation
This mitigation applies Anchor seed constraints to ensure that only valid program-derived addresses matching the creator and campaign name seeds are accepted.
Update the `FundContribute` structural accounts layout to explicitly validate the PDA seeds and bump:
```rust
pub struct FundContribute<'info> {
#[account(
mut,
seeds = [fund.name.as_bytes(), fund.creator.as_ref()],
bump
)]
pub fund: Account<'info, Fund>,
pub contributor: Signer<'info>,
// ... remaining accounts
}
```

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Impact 2

Proof of Concept

Recommended Mitigation

- remove this code
+ add this code
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 9 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!