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(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:
Impact:
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));
let first_secret = b"first secret";
set_secret(owner, first_secret);
let second_secret = b"second secret";
set_secret(owner, second_secret);
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 {});
+ }