code-423n4 / 2024-07-basin-validation

0 stars 0 forks source link

Unauthorized Contract Upgrade Vulnerability #69

Closed c4-bot-4 closed 3 months ago

c4-bot-4 commented 3 months ago

Lines of code

https://github.com/code-423n4/2024-07-basin/blob/7d5aacbb144d0ba0bc358dfde6e0cc913d25310e/src/WellUpgradeable.sol#L65

Vulnerability details

Impact

The identified vulnerability in the _authorizeUpgrade function of the UUPSUpgradeable contract allows unauthorized users to upgrade the contract. Without proper access control, malicious actors can upgrade the contract to a malicious implementation, potentially leading to severe consequences including:

Proof of Concept

function _authorizeUpgrade(address newImplmentation) internal view override {
        // verify the function is called through a delegatecall.
        require(address(this) != ___self, "Function must be called through delegatecall");

        // verify the function is called through an active proxy bored by an aquifer.
        address aquifer = aquifer();
        address activeProxy = IAquifer(aquifer).wellImplementation(_getImplementation());
        require(activeProxy == ___self, "Function must be called through active proxy bored by an aquifer");

        // verify the new implmentation is a well bored by an aquifier.
        require(
            IAquifer(aquifer).wellImplementation(newImplmentation) != address(0),
            "New implementation must be a well implmentation"
        );

        // verify the new implmentation is a valid ERC-1967 implmentation.
        require(
            UUPSUpgradeable(newImplmentation).proxiableUUID() == _IMPLEMENTATION_SLOT,
            "New implementation must be a valid ERC-1967 implmentation"
        );
    }

Tools Used

Recommended Mitigation Steps

To mitigate this vulnerability, it is essential to implement access control in the _authorizeUpgrade function to restrict upgrades to only authorized users. Use onlyOwner access modifier from OpenZeppelin

Assessed type

Access Control