Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

The `MondrianWallet::_validateSignature` returns always success

Summary

The MondrianWallet::_validateSignature function should validate the signature. But the function returns always success whether the signature is valid or not.

Vulnerability Details

The goal of the internal function MondrianWallet::_validateSignature is to validate the signature provided by the user.

function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash)
internal
pure
returns (uint256 validationData)
{
bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
ECDSA.recover(hash, userOp.signature);
@> return SIG_VALIDATION_SUCCESS;
}

The problem is that this function always returns SIG_VALIDATION_SUCCESS. The function doesn't check the return value from the ECDSA.recover(hash, userOp.signature);. That means if the user doesn't have a valid signature, the function will return SIG_VALIDATION_SUCCESS.

Impact

The MondrianWallet::_validateSignature function is called in the MondrianWallet::validateUserOp to validate the signature of the user:

function validateUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
external
virtual
override
requireFromEntryPoint
returns (uint256 validationData)
{
@> validationData = _validateSignature(userOp, userOpHash);
_validateNonce(userOp.nonce);
_payPrefund(missingAccountFunds);
}

The validateUserOp function does not explicitly check the validationData returned by _validateSignature. The function assumes a successful signature validation by returning the value from _validateSignature without conditional verification.
Also, the MondrianWallet::_validateSignature returns always SIG_VALIDATION_SUCCESS due to the incorrect implementation. This function will return success whether the signature is valid or not. That means the user without valid signature can execute transactions without the required permission.

Tools Used

Manual Review

Recommendations

Add the following changes to the _validateSignature function in order to ensure the signature is valid and the user has permission to execute a given transaction:

function _validateSignature(PackedUserOperation calldata userOp, bytes32 userOpHash)
internal
pure
returns (uint256 validationData)
{
bytes32 hash = MessageHashUtils.toEthSignedMessageHash(userOpHash);
- ECDSA.recover(hash, userOp.signature);
+ if (owner() != ECDSA.recover(hash, userOp.signature))
+ return SIG_VALIDATION_FAILED;
return SIG_VALIDATION_SUCCESS;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

ECDSA.recover should check against sender

`_validateSignature` SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch.

Support

FAQs

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