Weather Witness

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

Unauthorized Access

Author Revealed upon completion

Unauthorized Access to fulfillMintRequest Allows Interference with Minting

Description

  • Normal Behavior: Only the Chainlink router should call fulfillMintRequest after a valid oracle response.

  • Issue: The function lacks an onlyRouter check, so any address can call it after a response is set.

function fulfillMintRequest(bytes32 requestId) external {
bytes memory response = s_funcReqIdToMintFunctionReqResponse[requestId].response;
require(response.length > 0 || err.length > 0, WeatherNft__Unauthorized()); // @> Weak check
...
}

CopyEdit

// Root cause in the codebase with @> marks to highlight the relevant section

Risk

Likelihood:

  • After a valid oracle response is stored, any address can call the function.

Impact:

  • Malicious actors can interfere with minting and keeper logic.

  • Could lead to gas wastage or contract state corruption.

Proof of Concept

function testUnauthorizedFulfillMintRequest() public {
vm.deal(user, 1 ether);
vm.prank(user);
bytes32 requestId = weatherNft.requestMintWeatherNFT{value: 1 ether}("12345", "US", false, 1 hours, 0);
vm.prank(address(weatherNft.i_router));
weatherNft.fulfillRequest(requestId, abi.encode(uint8(0)), "");
vm.prank(attacker);
weatherNft.fulfillMintRequest(requestId); // Should revert
}

Recommended Mitigation

+ require(msg.sender == address(i_router), "Only Chainlink oracle");
Updates

Appeal created

bube Lead Judge 2 days 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.