Secret Vault on Aptos

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

`set_secret` can be called by anyone

Root + Impact

get_secret authorizes using a caller-supplied address and then always reads from hard-coded @owner. However, set\_secret writes under the transaction signer. Anyone can create a Vault and set a secret which contradicts the documentation. Any signer can set up the secret but will not be able to retrieve it via the get\_secret function (presuming that this function is correctly implemented).

Description

Only the specified owner address (in the .toml) should set and read their own secret. Currently, there is nothing preventing others from calling the set\_secret and setting up their own secrets.

public entry fun set_secret(caller: &signer, secret: vector<u8>) {

Risk

Anybody can set their own secret without having the ability to directly checking it out. The documentation clearly specifies that only the specific owner address can set and retrieve the secret.

Proof of Concept

#[test(user = @0xaa)]
#[expected_failure(major_status = NOT_OWNER, location = Self)]
fun test_set_secret_get_fail(user: &signer) {
use aptos_framework::account;
// Set up test environment
account::create_account_for_test(signer::address_of(user));
let secret = b"i'm a secret";
set_secret(user, sec);
let read = get_secret(signer::address_of(user));
assert!(read == string::utf8(secret), 9001);
}

Recommended Mitigation

If the idea is to only have a specific owner setting the secret :

+ public entry fun set_secret(caller: &signer, secret: vector<u8>) {
+ assert!(caller == @owner, NOT_OWNER);
+ let secret_vault = Vault { secret: string::utf8(secret) };
+ move_to(caller, secret_vault);
+ event::emit(SetNewSecret {});
}

If the idea is to having anybody set up a secret and retrieve it then :

- #[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 reveal_secret(owner: &signer): String acquires Vault {
+ assert!(exists<Vault>(addr));
+ let addr = signer::address_of(owner);
+ let v = borrow_global<Vault>(addr);
+ v.secret
+ }
Updates

Lead Judging Commences

bube Lead Judge 2 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

Anyone can call `set_secret` function

In Move for Aptos, the term "owner" refers to a signer, which is a verified account that owns a given resource, has permission to add resources and the ability to grant access or modify digital assets. Following this logic in this contest, the owner is the account that owns `Vault`. This means that anyone has right to call `set_secret` and then to own the `Vault` and to retrieve the secret from the `Vault` in `get_secret` function. Therefore, this group is invalid, because the expected behavior is anyone to call the `set_secret` function.

Appeal created

maroutis Submitter
2 months ago
bube Lead Judge
2 months ago
bube Lead Judge 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.