Secret Vault on Aptos

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

Read/Write Location Mismatch Result in DoS

Root + Impact

Description

According to the project's documentation, only the owner may set and retrieve their secret. However, there exists mismatch between set_secret() and get_secret():

  • set_secret() writes the Vault resource under the caller’s address

  • get_secret reads the Vault from a hardcoded address @owner

This result in read DoS if fixed @owner is differ from the caller of set_secret

public entry fun set_secret(caller:&signer,secret:vector<u8>){
let secret_vault = Vault{secret: string::utf8(secret)};
@> Write the Vault resource under the caller's address
move_to(caller,secret_vault);
event::emit(SetNewSecret {});
}
#[view]
public fun get_secret (caller: address):String acquires Vault{
assert! (caller == @owner,NOT_OWNER);
@> Reads the Vault from a hardcoded address @owner
let vault = borrow_global<Vault >(@owner);
vault.secret
}

Risk

Likelihood: High

  • unless the caller’s address exactly matches the bound @owner, it fails

Impact: High

  • Mismatch between storage and retrieval

  • Secrets may appear “missing” even though they were stored

Proof of Concept

Add the following test, then run the command: aptos move test -f test_read_write_mismatch

#[test(owner = @0xcc, user = @0x123)]
#[expected_failure]
fun test_read_write_mismatch(owner: &signer, user: &signer) acquires Vault {
use aptos_framework::account;
account::create_account_for_test(signer::address_of(owner));
account::create_account_for_test(signer::address_of(user));
// User stores a secret once.
set_secret(user, b"i'm a secret");
// User fails to read their own secret.
let leaked: String = get_secret(signer::address_of(user));
}

Recommended Mitigation

Align read and write to the same address authority:

  • Single-owner design: Enforce signer::address_of(caller) == @owner inside set_secret, and always write/read from @owner. This guarantees consistent access for the designated owner.

  • Multi-user design: Remove the hardcoded @owner. Instead, use signer::address_of(caller) consistently for both writing and reading, and consider adding an owner field inside the Vault resource for explicit ownership tracking.

Updates

Lead Judging Commences

bube Lead Judge about 2 months 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.