_authorizedUpgrade
does not implement any access resctriction. Consequently, anyone can upgrade the Mondrian wallet of any user to any new implementation contract.
The upgrade mechanism from a current implementation contract to a new one can be initiated by calling MondrianWallet2::upgadeToAndCall
(a function defined in the UUPSUpgradeable
contract). This function then calls MondrianWallett::_authorizedUpgrade
, a function that has to be implemented in the implementation contract as per required by UUPSUpgradeable
, which contract also states:
" The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
...
Function that should revert when msg.sender
is not authorized to upgrade the contract. Called by {upgradeToAndCall}.
Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
function authorizeUpgrade(address) internal onlyOwner {}"
However, MondiranWallet::_authorizeUpgrade
does not actually implement any access control.
The following test demonstrates if any non-owner user initiates the upgrade mechaism by calling upgradeToAndCall
, the upgrade runs successfully, as signified by the emitted event.
Malicious users can upgrade the Mondrian wallet of any user to any new implementation contract. They can implement whatever they want in the new implementation contract, including code that leads to loss of access and loss of funds for the true, original owner of the wallet.
Manual review, Foundry.
Restrict access to the owner as follows:
You could consider granting access not only to the owner but also to the Bootloader
, but in general it is best not to grant access to such critical functions to anyone but the owner.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.