Secret Vault on Aptos

First Flight #46
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Access Control in Set_secret Function

Description

The set_secret function in the smart contract is designed so that only a specific owner account can save a new secret in the vault. However, in the present code, there is no verification of the caller's identity. This means that any account can trigger set_secret, generating a personal Vault and storing it at their own address on chain.

Security Concerns

  • Unrestricted Access:
    Anyone can call set_secret and save their own secret, rather than this being limited to a predetermined owner.


  • Loss of Central Control:
    Instead of one trusted authority maintaining the secret, the contract now allows numerous vaults to be created, undermining the original intent and introducing unpredictability into the system's security assumptions.

Security Concerns

An attacker can simply submit a transaction with themselves as the signer:
let rogue_secret = b"exploit";
set_secret(attacker_signer, rogue_secret);
// This creates a Vault tied to the attacker's address, not the protected owner.

Risk:

  • Any external account can directly call set_secret without restriction.

  • No validation exists on signer::address_of(caller), making exploitation trivial and guaranteed.

Impact:

  • Breaks the "single owner" design, multiple users can create their own vaults.

  • Reduces trust assumptions: the contract no longer enforces central ownership.


Suggested Fix

Add a check at the start of set_secret to ensure only the owner’s account can perform this action:

assert!(signer::address_of(caller) == @owner, NOT_OWNER);

With this change, only transactions signed by the owner are allowed to create or update the Vault, ensuring exclusive control as originally intended. All unauthorized attempts will now fail.

Recommended Mitigation

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

Lead Judging Commences

bube Lead Judge 4 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.

Support

FAQs

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

Give us feedback!