HardhatFoundry
30,000 USDC
View results
Submission Details
Severity: low
Invalid

Improper `initData` input validations can lead to DOS and memory limit errors

Summary

In the Biconomy protocol, users deploy smart contracts through factory contracts by calling the createAccount function. This process eventually invokes the initializeAccount function in the Nexus contract to initialize the account. However, failure to validate the parameters, particularly arrays like validators and executors, can lead to critical issues such as memory limit errors and potential Denial of Service (DoS) attacks.

Vulnerability Details

The initializeAccount function in the Nexus contract is designed to initialize a new account with specified configurations:

function initializeAccount(bytes calldata initData) external payable virtual {
_initModuleManager();
(address bootstrap, bytes memory bootstrapCall) = abi.decode(initData, (address, bytes));
(bool success, ) = bootstrap.delegatecall(bootstrapCall);
require(success, NexusInitializationFailed());
}

This function decodes the initData parameter to extract the bootstrap address and bootstrapCall data, then performs a delegatecall to the bootstrap address.

A critical vulnerability arises if the parameters, particularly arrays such as validators and executors, are not properly validated. Without validation, malicious users can pass excessively large arrays, causing memory limit errors during execution. This can be demonstrated with the following test case:

Proof of Code

function test_POC() public payable {
BootstrapConfig[] memory validators = new BootstrapConfig[](100000000000000000);
validators[0].module = address(VALIDATOR_MODULE);
validators[0].data = initData;
BootstrapConfig[] memory executors;
BootstrapConfig memory hook = BootstrapLib.createSingleConfig(address(0), "");
BootstrapConfig[] memory fallbacks;
bytes memory saDeploymentIndex = "0";
bytes32 salt = keccak256(saDeploymentIndex);
// Create initcode and salt to be sent to Factory
bytes memory _initData = BOOTSTRAPPER.getInitNexusCalldata(validators, executors, hook, fallbacks, registry, attesters, threshold);
registryFactory.createAccount{ value: 1 ether }(_initData, salt);
}

In this test, an excessively large validators array is created with an unrealistic size. When this array is processed, it leads to memory limit errors, causing the transaction to fail.

Impact

If the Biconomy protocol does not validate the length and contents of the validators and executors arrays, it becomes susceptible to several issues:

  1. Memory Limit Errors: Processing excessively large arrays can exceed the Ethereum Virtual Machine's (EVM) memory limits, resulting in out-of-gas errors or reverting transactions.

  2. Denial of Service (DoS): Malicious users can exploit this vulnerability to cause repeated failures in contract initialization, effectively disrupting the normal operation of the protocol. This can lead to increased gas costs for legitimate users and degrade the overall reliability of the system.

Mitigation

These are the recommended mitigation.

  1. Array Length Validation: Before processing, validate the length of arrays such as validators and executors to ensure they are within reasonable bounds.

    require(validators.length < MAX_VALIDATORS, "Validators array too large");
    require(executors.length < MAX_EXECUTORS, "Executors array too large");
  2. Gas Limit Checks: Implement gas limit checks to abort processing if the gas usage exceeds safe limits.

    uint256 startGas = gasleft();
    for (uint256 i = 0; i < validators.length; i++) {
    require(gasleft() > MIN_GAS_REQUIRED, "Insufficient gas for processing");
    }
Updates

Lead Judging Commences

0xnevi Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

finding-loop-array-length-not-checked

Invalid [known issue [NonCritical-16]](https://github.com/Cyfrin/2024-07-biconomy/issues/1)

Support

FAQs

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