The requestMintWeatherNFT
The function allows a user to request the minting of a weather-based NFT, which is processed via Chainlink Functions. The corresponding fulfillMintRequest
function mints the NFT once a valid response is received. The expected behavior is that the NFT is minted to the original user who made the request.
However, there is a critical vulnerability in the fulfillMintRequest
function. It fails to verify the identity of the caller or ensure that the NFT is minted to the originally requesting user. Instead, it mints the NFT to msg.sender
, which can be any attacker calling the function before the legitimate response handler does.
This allows an attacker to steal NFTs by calling the function with a valid requestId
before the legitimate backend does.
Likelihood:
This occurs when an attacker observes a valid requestId
or listens for the WeatherNFTMintRequestSent
event.
Chainlink Functions do not restrict who can call fulfillMintRequest
, so any on-chain address can execute it before the legitimate fulfiller (oracle or backend) does.
Impact:
Attackers can front-run valid requests and mint NFTs that should have gone to other users.
Victims lose ETH (or LINK) during the mint process and receive nothing in return.
Retrieves the current tokenId
before minting begins.
Starts a broadcast using the user's private key.
Approves the WeatherNft contract to spend LINK tokens for Keeper registration.
Calls requestMintWeatherNFT
to initiate the mint process and emits an event with a unique requestId
.
It stops broadcasting after the mint request is sent.
Retrieves logs emitted during the transaction.
Iterates through the logs to find the WeatherNFTMintRequestSent
event and extract the corresponding requestId
.
Ensures that a valid requestId
value was retrieved by asserting it's not zero.
Used vm.prank
to impersonate the functionsRouter
(i.e., Chainlink Functions node).
Calls handleOracleFulfillment
with requestId
and a forged weather response (e.g., RAINY).
Starts a broadcast using an attacker’s private key.
Calls fulfillMintRequest
using the previously captured requestId
.
Mints the NFT to the attacker’s address instead of the legitimate user.
Ends the broadcast, completing the unauthorized NFT mint.
Additionally, implement a validation mechanism to ensure only trusted sources (e.g., the Chainlink Functions oracle) can fulfill the request:
Or, if applicable, use Chainlink Functions’ callbackGasLimit
and fulfill functions that support onlyFunctionsOracle
A pattern to restrict access to fulfillers.
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.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.