Bid Beasts

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

Anyone Can Burn Any NFT (Unauthorized Burn)

Description

  • In a standard ERC721 token contract, the burn function is designed to allow only the token owner or an approved operator to destroy a token, ensuring that NFTs cannot be arbitrarily removed from circulation without permission, which protects user assets and maintains the integrity of ownership records.

  • However, in this implementation, the burn function is declared as public and directly invokes the internal _burn method from OpenZeppelin's ERC721 without performing any ownership or approval checks, enabling any external caller to burn any existing token ID, regardless of who owns it, which can lead to irreversible destruction of NFTs and potential disruptions in associated contracts like the marketplace.

function burn(uint256 _tokenId) public {
@> _burn(_tokenId);
emit BidBeastsBurn(msg.sender, _tokenId);
}

Risk

Likelihood:

  • Tokens are minted and owned by users in the ecosystem at any point after deployment

  • Malicious actors scan for token IDs via events or queries and target them without restrictions

Impact:

  • Users suffer permanent loss of their NFTs, which may hold significant monetary or sentimental value

  • If burns occur on listed NFTs in the marketplace, it causes transfer failures during auction settlement, potentially locking bidder funds in the contract as transactions revert without proper cleanup

Proof of Concept

Add the following to the existing tests in BidBeastsMarketPlaceTest.t.sol

function test_UnauthorizedBurn() public {
// Step 1: Mint an NFT to the seller
_mintNFT(); // This mints TOKEN_ID (0) to SELLER
// Verify initial ownership
assertEq(nft.ownerOf(TOKEN_ID), SELLER, "NFT should be owned by SELLER initially");
// Step 2: Simulate an attacker burning the NFT
address attacker = address(0x5);
vm.prank(attacker);
nft.burn(TOKEN_ID);
// Step 3: Verify the NFT is burned (ownerOf should revert for non-existent token)
vm.expectRevert("ERC721: invalid token ID");
nft.ownerOf(TOKEN_ID);
}

Recommended Mitigation

Add an ownership check before burning the token to ensure only authorized parties can perform the action. This aligns with standard practices in ERC721Burnable from OpenZeppelin.

function burn(uint256 _tokenId) public {
+ require(_isApprovedOrOwner(msg.sender, _tokenId), "Caller is not owner nor approved");
_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!