Secret Vault on Aptos

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

The get_secret function can only be called successfully by the owner of the module, stopping all other users from reading their stored secrets.

The get_secret function can only be called successfully by the owner of the module, stopping all other users from reading their stored secrets.

Description

  • Normally, each user should be able to store and retrieve their own secret in the Vault resource under their address.

  • In the current implementation, any user can set their own secret using set_secret, but only the module owner can retrieve their secret using get_secret. All other users cannot retrieve their own secrets, making the vault functionality unusable for non-owner accounts.

public fun get_secret(caller: address): String acquires Vault {
@> assert!(caller == @owner, NOT_OWNER);
let vault = borrow_global<Vault >(@owner);
vault.secret

Risk

Likelihood:

The likelihood is High because:

  • Whenever a non-owner user calls get_secret with their own address, the assertion will fail and they will not be able to retrieve their secret.

Impact:

The impact is High because:

  • Non-owner users cannot access their own secrets.

  • The vault functionality is broken for all users except the owner.

Proof of Concept

The following test demonstrates that a non-owner cannot read their own secret:

#[test(owner = @0xcc, user = @0x123)]
#[expected_failure(abort_code = 1)]
fun test_user_cannot_read_own_secret(owner: &signer, user: &signer) acquires Vault {
use aptos_framework::account;
account::create_account_for_test(signer::address_of(user));
let secret = b"user secret";
set_secret(user, secret);
let user_addr = signer::address_of(user);
// This will fail the assertion and not return the secret
let leaked_secret = get_secret(user_addr);
}

Recommended Mitigation

Replace the caller parameter with a signer, and read the signer's secret instead.

- #[view]
- public fun get_secret(caller: address): String acquires Vault {
- assert!(caller == @owner, NOT_OWNER);
- let vault = borrow_global<Vault >(@owner);
- vault.secret
- }
+ public entry fun get_secret(caller: &signer): String acquires Vault {
+ let addr = signer::address_of(caller);
+ let vault = borrow_global<Vault>(addr);
+ vault.secret
+ }
Updates

Lead Judging Commences

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

The protocol doesn't work as intended

Support

FAQs

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