Secret Vault on Aptos

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

Broken Access Control Allows Anyone to Store Secrets, Violating Contract Purpose

Root + Impact

There is no access control on the set_secret(), leading to anyone setting their secret in the contract. This breaks the core purpose of the smart contract, which is to allow only the owner to set secrets

Description

Normal Behavior

According to the documentation, SecretVault should only allow the designated owner to store and retrieve secrets. Other users should not have access to create or read secrets.

Issue

The contract has two critical access control vulnerabilities:

  1. The set_secret function has no access control, allowing any user to store a secret at their address

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:

  • As long as the contract is there, anyone can call and set their secret

  • No access control needed to do set a secret in the contract

Impact:

  • breaks core functionality/ purpose of the contract

Proof of Concept

#[test(owner = @0xcc, user = @0x123)]
fun test_anyone_can_set_secret_vault(owner: &signer, user: &signer) acquires Vault{
use aptos_framework::account;
// Set up test environment
account::create_account_for_test(signer::address_of(owner));
account::create_account_for_test(signer::address_of(user));
// Create a new todo list for the user
let secret = b"i'm a secret";
set_secret(user,secret);
// Get the owner address
let owner_address = signer::address_of(owner);
let user_address = signer::address_of(user);
// Verify the secret was added
let valut = borrow_global<Vault>(user_address);
assert!(valut.secret == string::utf8(secret), 4);
debug::print(&b"All tests passed!");
}

Recommended Mitigation

+ const CONTRACT_OWNER: address = @0xcc;
...
public entry fun set_secret(caller: &signer, secret: vector<u8>) {
+ let caller_addr = signer::address_of(caller);
+ assert!(caller_addr == CONTRACT_OWNER, NOT_OWNER);
...
}
Updates

Lead Judging Commences

bube Lead Judge 18 days 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

kobbyeugene Submitter
18 days ago
bube Lead Judge
17 days ago
bube Lead Judge 16 days 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.