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 15 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.