Hawk High

First Flight #39
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Unprotected Initializer Vulnerability

Summary

The LevelOne contract has an unprotected initializer function that makes it vulnerable to unauthorized initialization and potential contract takeover. This vulnerability could allow an attacker to gain control of the entire system by initializing the contract with themselves as the principal.

Vulnerability Details

The initialize function in LevelOne.sol uses the initializer modifier from OpenZeppelin's Initializable contract but lacks additional security measures to prevent unauthorized initialization:

function initialize(address _principal, uint256 _schoolFees, address _usdcAddress) public initializer {
if (_principal == address(0)) {
revert HH__ZeroAddress();
}
if (_schoolFees == 0) {
revert HH__ZeroValue();
}
if (_usdcAddress == address(0)) {
revert HH__ZeroAddress();
}
principal = _principal;
schoolFees = _schoolFees;
usdc = IERC20(_usdcAddress);
__UUPSUpgradeable_init();

Furthermore, the _authorizeUpgrade function is too simplistic:

Furthermore, the _authorizeUpgrade function is too simplistic:

Slither analysis identified that "LevelOne is an upgradeable contract that does not protect its initialize functions" and warns that "Anyone can delete the contract with: UUPSUpgradeable.upgradeToAndCall(address,bytes)".

Impact

The impact of this vulnerability is critical:

  1. Contract Takeover: An attacker could initialize the contract with themselves as the principal, gaining administrative control

  2. Fund Theft: A malicious actor could steal all funds in the bursary

  3. System Destruction: The attacker could delete the contract via the upgradeToAndCall function

  4. Compromise of Educational Integrity: All educational processes could be manipulated

Tools Used

  • Slither static analysis tool

  • Manual code review

Recommendations

Strengthen the _authorizeUpgrade Function:

function _authorizeUpgrade(address newImplementation) internal override onlyPrincipal {
require(newImplementation != address(0), "Invalid implementation address");
// Additional security checks as needed
}

Restrict initialize Function:

// Consider restricting who can call initialize
function initialize(address _principal, uint256 _schoolFees, address _usdcAddress) public initializer {
require(msg.sender == TRUSTED_DEPLOYER, "Unauthorized initialization");
// Rest of the initialization code
}

Updates

Lead Judging Commences

yeahchibyke Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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