HardhatFoundry
30,000 USDC
View results
Submission Details
Severity: high
Valid

Installing validators with enable mode in `validateUserOp()` doesn't check `moduleType`

Summary

_checkEnableModeSignature() doesn't check that moduleType is permitted by the owner's signature.

Vulnerability Details

When Nexus account owners send a transaction with enable mode in PackedUserOperation.nonce, validateUserOp() calls _enableMode() to install the validator as a new module.

Nexus.sol#L108-L109

PackedUserOperation memory userOp = op;
userOp.signature = _enableMode(validator, op.signature);

The moduleType and moduleInitData of the validator to be installed is decoded from PackedUserOperation.signature:

ModuleManager.sol#L166-L171

(moduleType, moduleInitData, enableModeSignature, userOpSignature) = packedData.parseEnableModeData();
_checkEnableModeSignature(
_getEnableModeDataHash(module, moduleInitData),
enableModeSignature
);
_installModule(moduleType, module, moduleInitData);

As seen from above, to ensure that the account owner has allowed the validator to be installed with moduleInitData, module and moduleInitData are hashed, and the hash is checked to be signed by the owner with enableModeSignature.

However, moduleType is not included in the hash, as seen in _getEnableModeDataHash():

ModuleManager.sol#L388-L398

function _getEnableModeDataHash(address module, bytes calldata initData) internal view returns (bytes32 digest) {
digest = _hashTypedData(
keccak256(
abi.encode(
MODULE_ENABLE_MODE_TYPE_HASH,
module,
keccak256(initData)
)
)
);
}

This allows a malicious relayer/bundler to call validateUserOp() and specify moduleType as any module type. For example, instead of MODULE_TYPE_VALIDATOR, the attacker can specify it as MODULE_TYPE_EXECUTOR.

If the validator happens to be a multi-type module, this is problematic an attacker can install the validator with any module type, without the owner's permission.

Impact

An attacker can install validators through enable mode and validateUserOp() with any module type, without permission from the owner.

Depending on the module being installed, this can have drastic consequences on the account, with the highest impact being executor modules as they can delegatecall.

Recommendations

If _enableMode() is only meant to install validators, consider calling _installModule() with MODULE_TYPE_VALIDATOR instead of having it as a parameter.

Otherwise, include moduleType in the hash returned by _getEnableModeDataHash(). This ensures that the module type is permitted by the account owner's signature.

Updates

Lead Judging Commences

0xnevi Lead Judge
10 months ago
0xnevi Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Appeal created

0xnevi Lead Judge
10 months ago
0xnevi Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-enable-mode-malleable-module-type

Support

FAQs

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