Secret Vault on Aptos

First Flight #46
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Severity: high
Valid

Bypassable access control in `#[view] get_secret`

Root + Impact

Description

  • get_secret checks assert!(caller == @owner, NOT_OWNER), but caller is a user-supplied parameter. Any caller can pass @owner and satisfy the assertion.

// secret_vault.move
#[view]
public fun get_secret(caller: address): String acquires Vault {
@> assert!(caller == @owner, NOT_OWNER); // user-controlled parameter
let vault = borrow_global<Vault>(@owner);
@> vault.secret
}

Risk

Likelihood:

  • Whenever get_secret is callable, any external user can pass caller = @owner and bypass the check.

Impact:

  • Secret is exposed to any user.

Proof of Concept

// Pseudo-call via script or SDK:
let leaked = secret_vault::vault::get_secret(@owner);
// Works for any caller because `caller` is just an argument, not an authenticated signer.

Recommended Mitigation

- #[view]
- public fun get_secret(caller: address): String acquires Vault {
- assert!(caller == @owner, NOT_OWNER);
- let v = borrow_global<Vault>(@owner);
- v.secret
- }
+ // Do not implement plaintext getters. There is no way to enforce secrecy in a view.
Updates

Lead Judging Commences

bube Lead Judge 19 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of signer check in `get_secret`

Support

FAQs

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