Secret Vault

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

M-02- DoS on Updating a Secret

Root + Impact

Description:

The set_secret function uses move_to to store the Vault resource.
In Move, move_to will abort if the resource already exists for that account.
Since there is no update_secret or remove_secret function, once a vault is created, its secret can never be updated or deleted.

This creates a denial of service for the legitimate owner — they are locked into their first secret permanently.

public entry fun set_secret(caller:&signer,secret:vector<u8>){
let secret_vault = Vault{secret: string::utf8(secret)};
// move_to will fail if the account already has a Vault (you must remove it first).
@> move_to(caller,secret_vault);
event::emit(SetNewSecret {});
}

move_to will abort when a Vault already exists for the caller’s address, and there is no alternate path to update it.

Risk

Likelihood:

  • Happens whenever a user tries to change their secret after the first time.

  • No available function to perform this action.

Impact:

  • Users cannot rotate or change their secrets.

  • Permanent data lockout unless they destroy the account.

Proof of Concept

Test function:

Expected: Secret is updated to "new secret".
Actual: Transaction aborts — secret is permanently stuck as "first secret".

#[test(owner = @0xcc)]
fun test_secret_update_dos(owner: &signer) acquires Vault {
use aptos_framework::account;
account::create_account_for_test(signer::address_of(owner));
// First time: works fine
let first_secret = b"first secret";
set_secret(owner, first_secret);
// Second time: will ABORT because Vault already exists
let second_secret = b"second secret";
// This call will fail with MOVE_ABORT due to move_to on existing resource
set_secret(owner, second_secret);
// If the call above somehow passed, we would check the updated value
let vault = borrow_global<Vault>(signer::address_of(owner));
assert!(vault.secret == string::utf8(second_secret), 999);
}
## This is an test case ,it will give abbort an error ,only one owner assign one resoruce at a time
SCATERLABs/Auditing/FirstFlight/2025-07-secret-vault$ aptos move test --filter test_secret_update_dos
INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING aptos-secret-vault
Running Move unit tests
[ FAIL ] 0x234::vault::test_secret_update_dos
Test failures:
Failures in 0x234::vault:
┌── test_secret_update_dos ──────
│ error[E11001]: test failure
│ ┌─ /home/nithin/SCATERLABs/Auditing/FirstFlight/2025-07-secret-vault/sources/secret_vault.move:24:6
│ │
│ 19 │ public entry fun set_secret(caller:&signer,secret:vector<u8>){
│ │ ---------- In this function in 0x234::vault
│ ·
│ 24 │ move_to(caller,secret_vault);
│ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Test was not expected to error, but it gave a RESOURCE_ALREADY_EXISTS (code 4004) error with error message: "Failed to move resource into 00000000000000000000000000000000000000000000000000000000000000cc". Error originating in the module 0000000000000000000000000000000000000000000000000000000000000234::vault rooted here
│ stack trace
│ vault::test_secret_update_dos(/home/nithin/SCATERLABs/Auditing/FirstFlight/2025-07-secret-vault/sources/secret_vault.move:107)
└──────────────────
Test result: FAILED. Total tests: 1; passed: 0; failed: 1
{
"Error": "Move unit tests failed"
}

Recommended Mitigation

Check if the vault exists before storing.
If it exists, update the secret via borrow_global_mut; otherwise, create a new vault.

+ public entry fun set_or_update_secret(caller: &signer, secret: vector<u8>) acquires Vault {
+ let addr = signer::address_of(caller);
+
+ if (exists<Vault>(addr)) {
+ let vault = borrow_global_mut<Vault>(addr);
+ vault.secret = string::utf8(secret);
+ } else {
+ move_to(caller, Vault { secret: string::utf8(secret) });
+ }
+
+ 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.