Secret Vault

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

Secret cannot be updated, no update path (owner cannot change secret due to move_to overwrite abort)

Root + Impact

Description

  • Normal behaviour is that owner can use update vault

  • Current behaviour owner cannot update secret, due to move_to overwrite abort.

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

Risk

Likelihood: High

  • Straightforward path: anyone can call set_secret to change a secret.

  • The current architecture allows one secret per vault, so the update is the intended behavior.

Impact:

  • The current architecture allows one secret per vault, so the update is the intended behavior.

  • Breaks functionality and disrupts the intended path.

Proof of Concept

This test proves that the owner cannot update the secret because move_to cannot overwrite an existing resource.

#[test(owner = @0xcc)]
#[expected_failure]
public fun test_owner_cannot_update_secret(owner: &signer) {
account::create_account_for_test(signer::address_of(owner));
let secret1 = b"first";
let secret2 = b"second";
vault::set_secret(owner, secret1);
// This should abort because move_to cannot overwrite an existing resource
vault::set_secret(owner, secret2);
}

Recommended Mitigation

This mitigation allows the owner to update the secret or create a vault and set an initial secret. Additionally, this code enforces access restrictions, allowing only the owner to set or update a secret.

- public entry fun set_secret(caller:&signer,secret:vector<u8>){
+ public entry fun set_secret(caller: &signer, secret: vector<u8>) acquires Vault {
+ assert!(signer::address_of(caller) == @owner, NOT_OWNER);
+ if (exists<Vault>(@owner)) {
+ let vault_ref = borrow_global_mut<Vault>(@owner);
+ vault_ref.secret = string::utf8(secret);
+ } else {
+ move_to(caller, Vault { secret: string::utf8(secret) });
+ }
let secret_vault = Vault{secret: string::utf8(secret)};
move_to(caller,secret_vault);
}
event::emit(SetNewSecret {});
}
Updates

Lead Judging Commences

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

The `secret` can not be updated

Support

FAQs

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