Mystery Box

First Flight #25
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

[H-01] Unrestricted changeOwner Function

Summary

The changeOwner(address _newOwner) function in the MysteryBox contract
currently allows any user to change the contract's owner to an arbitrary
address. This lack of access control creates a significant security
vulnerability, enabling any external user to call this function and assign
ownership to themselves or another address.

Vulnerability Details

In the MysteryBox::changeOwner() function, there are no access control
checks implemented, which permits any user to change the contract's
ownership. This is a critical vulnerability as ownership typically grants
significant control over the contract, including the ability to perform
privileged actions such as withdrawing funds or managing key contract
parameters.

function changeOwner(address _newOwner) public {
owner = _newOwner;
}

Impact

An attacker could exploit this vulnerability by calling the changeOwner()
function to set themselves or another address as the new owner. With
control over the contract's ownership, the attacker could:

  1. Modify the Box Price: Call setBoxPrice() to change the price of mystery
    boxes to an arbitrary value, potentially leading to financial loss for
    legitimate users.

  2. Manipulate Rewards: Call addReward() to alter the rewards system,
    undermining the contract's intended functionality.

  3. Drain Funds: Call withdrawFunds() to extract the contract's ETH balance,
    resulting in the loss of funds for all users.

Tools Used

Manual Code Review

Recommendations

To mitigate this vulnerability, it is essential to restrict the
changeOwner() function so that only the current owner of the contract can
invoke it. This can be achieved by implementing an access control
modifier, such as onlyOwner.

Implementation Steps

Add the onlyOwner Modifier: Define the onlyOwner modifier to check that
the caller is the current owner of the contract:

modifier onlyOwner() {
require(msg.sender == owner, "Not the contract owner");
_;
}

Modify the changeOwner() function to include the onlyOwner modifier,
ensuring that only the current owner can change ownership.

function changeOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}

Secure Other Sensitive Functions: Additionally, apply the onlyOwner
modifier to other sensitive functions like setBoxPrice(), addReward(),
and withdrawFunds(). This approach not only enhances security but also
saves gas costs compared to using multiple require statements:

By implementing these recommendations, the MysteryBox contract will be
significantly more secure, protecting it from unauthorized ownership
changes and potential exploitation.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago

Appeal created

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Anyone can change owner

Support

FAQs

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