Bid Beasts

First Flight #49
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Anyone can burn token on behalf of the minter

Lack of access control to burn function, malicious actor can burn NFT on behalf of the minter

Description

  • ERC721 documentation states that _burn does not check if the sender is authorized to operate on the token. The implementation of burn does not constrain who can call it. Therefore, any arbitrary address can burn an NFT on behalf of its owner, causing the owner to lose the NFT that should belong to them.

function burn(uint256 _tokenId) public {

Risk

Likelihood:

  • The function is public, and can be called at all times, regardless if it is in auction or not.

Impact:

  • Owner will lose access to their NFT

  • There can be still ongoing auction regarding the burnt NFT, causing logic errors in the auction.

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
import {Test} from "forge-std/Test.sol";
import {IERC721Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
import {BidBeasts} from "../src/BidBeasts_NFT_ERC721.sol";
contract burn is Test {
function testFuzz_any_address_can_burn_existing_token(
address _owner,
address _minter,
address _actor
) public {
vm.assume(_owner != address(0) && _minter != address(0) && _actor != address(0));
vm.assume(_owner != _minter && _owner != _actor && _minter != _actor);
vm.assume(_minter.code.length == 0);
vm.startPrank(_owner);
BidBeasts bidBeasts = new BidBeasts();
uint256 _tokenId = bidBeasts.mint(_minter);
vm.stopPrank();
assertEq(bidBeasts.ownerOf(_tokenId), _minter);
vm.prank(_actor);
bidBeasts.burn(_tokenId);
assertEq(bidBeasts.balanceOf(_minter), _tokenId);
vm.expectRevert(
abi.encodeWithSelector(
IERC721Errors.ERC721NonexistentToken.selector,
_tokenId
)
);
bidBeasts.ownerOf(_tokenId);
}
}

Recommended Mitigation

  • By checking if msg.sender is owner of the token, we can prevent non owner from burning the token.

- remove this code
function burn(uint256 _tokenId) public {
_burn(_tokenId);
emit BidBeastsBurn(msg.sender, _tokenId);
}
+ add this code
function burn(uint256 _tokenId) public {
if (ownerOf(_tokenId) != msg.sender)
revert();
_burn(_tokenId);
emit BidBeastsBurn(msg.sender, _tokenId);
}
Updates

Lead Judging Commences

cryptoghost Lead Judge 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

BidBeasts ERC721: Anyone Can Burn

In the BidBeasts ERC721 implementation, the burn function is publicly accessible, allowing any external user to burn NFTs they do not own. This exposes all tokens to unauthorized destruction and results in permanent asset loss.

Support

FAQs

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

Give us feedback!