Using self.signer in bond_validator can allow external malicious programs to drain the signers microcredits
Summary
Using self.signer in bond_validator can allow external malicious programs to drain the signers microcredits
Vulnerability Detail
self.signer is equivalent to tx.origin, where the self.signer is the originator of the transaction.
This creates a huge risk when used in bond_validator because a malicious Aleo program in the call flow can make an external call to bond_validator in credits.aleo which can cause an eligible validator with 10M total delegated credits that originated the transaction to bond without their consent.
// The `transfer_public_as_signer` function sends the specified amount
// from the signer's `account` to the receiver's `account`.
function bond_validator:
// Input the withdrawal address.
input r0 as address.public;
// Input the amount of microcredits to bond.
input r1 as u64.public;
// Input the commission percentage.
input r2 as u8.public;
// Ensure the withdrawal address is not the validator address.
assert.neq self.signer r0;
// Determine if the amount is at least 1 credit.
gte r1 1_000_000u64 into r3;
// Enforce the amount is at least 1 credit.
assert.eq r3 true;
// Ensure the commission percentage does not exceed 100%.
gt r2 100u8 into r4;
assert.neq r4 true;
// Bond the specified amount of microcredits to the specified validator.
async bond_validator self.signer r0 r1 r2 into r5;
// Output the finalize future.
output r5 as credits.aleo/bond_validator.future;
Impact
An attack path to fully drain all the credits is as follows:
Victim first calls a malicious Aleo program in the call flow, which first delegates 10M credits to the user.
The Aleo program calls bond_validator with an attacker-controlled address as the withdrawal address, all the microcredits of the victim and an arbitrary commission percentage
Then the attacker-controlled withdrawal address will call unbond_public on the victim
Once the unbonding process is done (after 360 blocks passed), the attacker-controlled withdrawal address can then claim back the victim's microcredits, thus having fully drained them.
haxatron
High
Using
self.signer
inbond_validator
can allow external malicious programs to drain the signers microcreditsSummary
Using
self.signer
inbond_validator
can allow external malicious programs to drain the signers microcreditsVulnerability Detail
self.signer
is equivalent totx.origin
, where theself.signer
is the originator of the transaction.This creates a huge risk when used in
bond_validator
because a malicious Aleo program in the call flow can make an external call tobond_validator
incredits.aleo
which can cause an eligible validator with 10M total delegated credits that originated the transaction to bond without their consent.https://github.com/sherlock-audit/2024-05-aleo/blob/main/snarkVM/synthesizer/program/src/resources/credits.aleo#L159-L182
Impact
An attack path to fully drain all the credits is as follows:
bond_validator
with an attacker-controlled address as the withdrawal address, all the microcredits of the victim and an arbitrary commission percentageunbond_public
on the victimCode Snippet
https://github.com/sherlock-audit/2024-05-aleo/blob/main/snarkVM/synthesizer/program/src/resources/credits.aleo#L159-L182
Tool used
Manual Review
Recommendation
Use
self.caller
which is equivalent tomsg.sender
Duplicate of #15