Closed code423n4 closed 1 year ago
gzeon-c4 marked the issue as primary issue
not quite sure, need further review
imo validateSignature would have failed prior to getting this stage! can you showcase this with proof of test case?
to replay the second op (after the wallet is already deployed) nonce is zero but you will also need to send initcode exactly the same! (when it is 0x for first op) and the userOp signature is signed over the whole struct so it will either fail with signature mismatch, or createSenderIfNeeded will revert (if you send same signature and initcode!)
livingrockrises marked the issue as sponsor disputed
livingrockrises marked the issue as disagree with severity
livingrockrises requested judge review
gzeon-c4 marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/BaseSmartAccount.sol#L64
Vulnerability details
Impact
During handling an UserOperation, if the smart account is not deployed already, it will be created and then the UserOperation will be executed. The vulnerability is that since the smart account is going to be deployed before the execution of the UserOperation, it will bypass the nonce incrementation. This provides an opportunity to apply replay attack to execute the same UserOperation twice.
Replaying a user's transaction can have critical financial impact on the user. For example, transferring fund from the user to the receiver twice instead of once.
Proof of Concept
handleOps
will be called by the bundler to validate and execute them. https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/aa-4337/core/EntryPoint.sol#L68initCode.length != 0
, the following function will deploy the Alice's smart account.https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/aa-4337/core/EntryPoint.sol#L261
https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/BaseSmartAccount.sol#L60
initCode.length != 0
, the validation of nonce will be bypassed, and it will not increment either. So, the nonce will still remain zero.handleOps
himself and gives the same Alice's UserOperation as a parameter to execute Alice's UserOperation again.initCode.length = 0
, the_createSenderIfNeeded
will not be executed. Instead, duringvalidateUserOp
, the function_validateAndUpdateNonce
will be called. https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L501https://github.com/code-423n4/2023-01-biconomy/blob/5df2e8f8c0fd3393b9ecdad9ef356955f07fbbdd/scw-contracts/contracts/smart-contract-wallet/SmartAccount.sol#L501
Tools Used
Recommended Mitigation Steps
Whether change the increment order:
Or, remove the condition
initCode.length == 0