Mystery Box

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

Lack of Access Control in changeOwner Function

Summary

The changeOwner function in the contract lacks access control, meaning any external user (including attackers) can call this function and change the contract’s owner. This allows unauthorized users to take over the contract and gain full administrative control.

Vulnerability Details

The changeOwner function in the contract lacks access control, meaning any external user (including attackers) can call this function and change the contract’s owner. This allows unauthorized users to take over the contract and gain full administrative control.

// MysteryBox.sol: line 111 to 123
function changeOwner(address _newOwner) public {
owner = _newOwner;
}
  1. Root Cause:

    • The changeOwner function is missing a check to ensure that only the current owner can update the owner address. This function is publicly accessible, allowing any address to call it and change the contract's ownership to themselves or any arbitrary address.

  2. Risks:

    • Unauthorized Contract Takeover: Attackers can call the changeOwner function and set themselves or another malicious address as the contract owner. This would give them complete control over any privileged actions, including fund withdrawals, contract upgrades, or other sensitive administrative operations.

    • Loss of Control: The original owner or the contract’s legitimate stakeholders will lose all control over the contract if an attacker successfully changes the owner.

    • Financial and Operational Damage: The attacker, once the owner, can withdraw funds, alter the contract’s configuration, or lock out all legitimate users and administrators, potentially leading to significant financial and operational harm.

  3. Affected Components:

    • The changeOwner function is directly impacted, but the broader effect of this vulnerability impacts all administrative and sensitive functionalities that require the owner to manage the contract, such as fund management, contract upgrades, or parameter adjustments.

  4. Attack Scenarios:

    • Unauthorized Owner Change: An external attacker can call the changeOwner function, passing their own address or another malicious address as the new owner. Once successful, they can gain full administrative privileges and take control of the contract.

    • Operational Disruption: An attacker can repeatedly change ownership between malicious accounts or even set ownership to a random address, leading to denial of service (DoS) by confusing or blocking legitimate administrative access.

Impact

Unauthorized Ownership Takeover: Since the changeOwner function lacks an onlyOwner check, anyone can call this function and replace the current owner with their own address. This effectively transfers all control over the contract to the attacker.

  • Loss of Funds and Assets: If the contract manages funds or other valuable assets (such as tokens, NFTs, or sensitive data), the new unauthorized owner would gain full control. The attacker can withdraw all assets, resulting in irreversible loss of funds.

  • Denial of Service: An attacker could change the ownership multiple times or to an unresponsive address (e.g., a dead address or smart contract that doesn't support transfers), effectively locking the original owner out of the contract and causing a Denial of Service (DoS).

  • Reputation Damage: If the contract is part of a business or service, a successful attack could severely harm the project's reputation, resulting in loss of trust from users, investors, and partners.

  • Loss of Contract Functionality: Any functions in the contract that rely on the owner for critical operations (such as upgrades, withdrawals, or administrative actions) would be under the attacker's control. This could result in the complete shutdown of key contract functionality.

Tools Used

Recommendations

To prevent unauthorized access to the changeOwner function, implement an ownership check. Only the current owner should have the ability to change ownership. For example, use the onlyOwner modifier (if using OpenZeppelin’s Ownable library) or implement custom access control logic.

If you're using OpenZeppelin's Ownable library:

// Import OpenZeppelin's Ownable contract
import "@openzeppelin/contracts/access/Ownable.sol";
contract YourContract is Ownable {
// The changeOwner function is now secured by the onlyOwner modifier
function changeOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}
}
// If you're not using OpenZeppelin, you can implement your own onlyOwner modifier:
// Implement custom ownership logic
contract YourContract {
address public owner;
// Modifier to check if the caller is the owner
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}
constructor() {
// Set the initial owner to the contract deployer
owner = msg.sender;
}
// The changeOwner function is now secured by the onlyOwner modifier
function changeOwner(address _newOwner) public onlyOwner {
owner = _newOwner;
}
}
Updates

Appeal created

inallhonesty Lead Judge 11 months 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.