Weather Witness

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

Unauthorized Fulfillment of Mint Requests

Root + Impact

Description:Request ID Exploitation for Unauthorized NFT Minting,
A malicious user can observe blockchain events to extract the requestId generated during a mint request and use it to call fulfillMintRequest(requestId) to mint an NFT, even if they are not the original msg.sender who initiated the mint request


The vulnerability lies in the fulfillMintRequest function, which does not validate the caller's identity:

function fulfillMintRequest(bytes32 requestId) external {
bytes memory response = s_funcReqIdToMintFunctionReqResponse[requestId].response;
bytes memory err = s_funcReqIdToMintFunctionReqResponse[requestId].err;
require(response.length > 0 || err.length > 0, WeatherNft__Unauthorized());
if (response.length == 0 || err.length > 0) {
return;
}
UserMintRequest memory _userMintRequest = s_funcReqIdToUserMintReq[requestId];
uint8 weather = abi.decode(response, (uint8));
uint256 tokenId = s_tokenCounter;
s_tokenCounter++;
emit WeatherNFTMinted(
requestId,
msg.sender, // Vulnerability: No validation of msg.sender
Weather(weather)
);
_mint(msg.sender, tokenId); // Vulnerability: NFT is minted to msg.sender
s_tokenIdToWeather[tokenId] = Weather(weather);
}hbj

Risk: The fulfillMintRequest function does not validate that the caller is the original user who initiated the mint request.

  • Initial State: A user initiates a mint request, and the requestId is emitted in the WeatherNFTMintRequestSent event.

  • Step 1: A malicious user observes the blockchain event and extracts the requestId.

  • Step 2: The malicious user calls fulfillMintRequest(requestId) to mint an NFT.

  • Outcome: The malicious user mints an NFT they did not pay for.

  • Implications: This leads to unauthorized minting, financial losses for legitimate users, and potential abuse of the system.


Recommended Mitigation:To fix this vulnerability, add a validation check to ensure that only the original user who initiated the mint request can call fulfillMintRequest.

// Ensure only the original user can fulfill the mint request
UserMintRequest memory _userMintRequest = s_funcReqIdToUserMintReq[requestId];
require(
msg.sender == _userMintRequest.user,
"WeatherNft__UnauthorizedCaller"
);
Updates

Appeal created

bube Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Lack of ownership check in `fulfillMintRequest` function

There is no check to ensure that the caller of the `fulfillMintRequest` function is actually the owner of the `requestId`. This allows a malicious user to receive a NFT that is payed from someone else.

Support

FAQs

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