Anybody can execute arbitrary transactions on any SmartAccount via execTransaction
#50
Labels
3 (High Risk)
Assets can be stolen/lost/compromised directly
bug
Something isn't working
duplicate-175
satisfactory
satisfies C4 submission criteria; eligible for awards
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Lines of code
https://github.com/code-423n4/2023-01-biconomy/blob/53c8c3823175aeb26dee5529eeefa81240a406ba/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L192
https://github.com/code-423n4/2023-01-biconomy/blob/main/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L314-L343
Vulnerability details
Impact
Anybody can execute any transaction they want on behalf of any SmartAccount via the execTransaction function.
Anybody can get any SmartAccount to execute any transaction they want as long as it is done through a contract account. For instance, transfer out all Ether, ERC20, and ERC721, or do any operation to which the SmartAccount has access.
Proof of Concept
Here is a simple example attack to illustrate the concept. In the example, 1 Ether is stolen. However, the transaction provided to the
smartAccount.execTransaction
function can be anything.The root cause of this vulnerability layers in the
SmartContract.checkSignatures
function. The problem is that when the signature is a contract signature (v == 0
). There is no check that the signer (_signer
) is the owner. It checks that it's a valid signature but not who the signer is.Tools Used
Manual review.
Recommended Mitigation Steps
Add the
require(_signer == owner, "INVALID_SIGNATURE");
check in the case of a contract signature (v == 0
).Or, since all paths should make this check, add the check at the end of the
checkSignatures
function outside conditional statements.Another alternative is removing the whole case of allowing contract signatures.
The text was updated successfully, but these errors were encountered: