Secret Vault on Aptos

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

Attacker Can Read Owner's Secret

Description

  • Normal behavior: Each user's vault should be private, accessible only by that user.

  • Issue: The get_secret function checks against a hardcoded owner (@owner) instead of the caller, allowing any user to read the owner's secret.

// Root cause in the codebase
public fun get_secret(caller: address): String acquires Vault {
assert!(caller == @owner, NOT_OWNER); // @> hardcoded owner allows any caller to pass @owner
let vault = borrow_global<Vault>(@owner);
vault.secret
}

Risk

Likelihood:

  • Any user can call get_secret using the owner’s address.

  • Happens whenever dApps or other contracts retrieve vault secrets.

Impact:

  • Secrets can be publicly exposed.

  • Could enable further attacks or information leakage in dependent systems.

Proof of Concept

#[test(owner = @0xcc, attacker = @0x4123)]
fun test_attacker_can_read_secret(owner: &signer, attacker: &signer) acquires Vault {
use aptos_framework::account;
use std::debug;
account::create_account_for_test(signer::address_of(owner));
account::create_account_for_test(signer::address_of(attacker));
let secret = b"top-secret";
set_secret(owner, secret);
let leaked = get_secret(@0xcc); // Attacker reads the owner's secret
debug::print(&leaked);
}

Recommended Mitigation

- assert!(caller == @owner, NOT_OWNER);
+ assert!(exists<Vault>(caller), NOT_OWNER);
+ let vault = borrow_global<Vault>(caller);
Updates

Lead Judging Commences

bube Lead Judge 17 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.