SSSwap

First Flight #41
Beginner FriendlyRust
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Unverified Check: from.owner != authority.key()

Root + Impact

https://github.com/CodeHawks-Contests/2025-05-ssswap/blob/27a2ef878023b0111ec4acc33503d99ae1ae36fa/programs/amm/src/instructions/transfer.rs#L12-L17

Description

  • only the actual owner of the from TokenAccount is allowed to authorize token transfers.

  • This function accepts an authority: Signer account but does not verify it actually matches from.owner.

// transfer_tokens() implementation
TransferChecked {
...
authority: authority.to_account_info(), // @> No check if this matches from.owner
}

Risk

Likelihood:

  • Any signer account can be passed as authority, regardless of ownership over from.

  • Developers assume authority is correct but do not verify this at runtime.

Impact:

Lead to authorization bypass

Proof of Concept

attacker signs with their own account, not the real owner

transfer_tokens(
from: victim_token_account,
to: attacker_receiver_account,
mint: correct_mint,
authority: attacker_signer,
...
);

Recommended Mitigation

pub fn transfer_tokens<'info>(...) -> Result<()> {
+ require!(from.owner == authority.key(), CustomError::InvalidAuthority);
...
let transfer_account_options = TransferChecked {
...
};
Updates

Lead Judging Commences

0xtimefliez Lead Judge 6 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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