Weather Witness

First Flight #40
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: high
Invalid

Insufficient Input Parameter Validation in NFT Minting Process

Description

The requestMintWeatherNFT function accepts parameters without proper validation, potentially leading to invalid or malformed data being stored on-chain.

Risk

Severity: Medium
Likelihood: High

Summary

Missing input validation for pincode, isoCode, and heartbeat parameters could lead to system instability and increased oracle costs.

Vulnerability Details

Root Cause: Lack of input validation checks in the minting function.

Initial State: System accepts any string/number inputs without validation.

Attack Scenario:

  1. Attacker provides invalid pincode format

  2. System attempts to fetch weather data with invalid location

  3. Oracle calls fail but consume resources

  4. Invalid data gets stored on-chain

Proof of Concept

// Test demonstrating the vulnerability
function testInvalidInputs() public {
// Can mint with empty pincode
weatherNft.requestMintWeatherNFT{value: 1 ether}(
"", // empty pincode
"XXX", // invalid ISO code (should be 2 chars)
false,
0, // invalid heartbeat
0
);
// Can mint with malformed data
weatherNft.requestMintWeatherNFT{value: 1 ether}(
"!@#$%", // invalid pincode
"USAA", // invalid ISO code
false,
1, // too short heartbeat
0
);
}

Impact

  • Oracle calls fail but consume resources

  • Invalid location data stored on-chain

  • Increased gas costs for users

  • Unreliable weather data updates

  • System credibility compromised

Tools Used

  • Manual Review

  • Static Analysis

  • Fuzzing Tests

Recommendations

Add comprehensive input validation:

contract WeatherNft {
uint256 private constant MIN_HEARTBEAT = 1 hours;
uint256 private constant MAX_HEARTBEAT = 30 days;
error InvalidPincode(string pincode);
error InvalidIsoCode(string isoCode);
error InvalidHeartbeat(uint256 heartbeat);
function validateInputs(
string memory _pincode,
string memory _isoCode,
uint256 _heartbeat
) internal pure {
// Validate pincode format (assuming 6 digits)
bytes memory pincodeBytes = bytes(_pincode);
if(pincodeBytes.length != 6) revert InvalidPincode(_pincode);
for(uint i = 0; i < pincodeBytes.length; i++) {
if(uint8(pincodeBytes[i]) < 48 || uint8(pincodeBytes[i]) > 57)
revert InvalidPincode(_pincode);
}
// Validate ISO code (2 uppercase letters)
bytes memory isoBytes = bytes(_isoCode);
if(isoBytes.length != 2) revert InvalidIsoCode(_isoCode);
for(uint i = 0; i < isoBytes.length; i++) {
if(uint8(isoBytes[i]) < 65 || uint8(isoBytes[i]) > 90)
revert InvalidIsoCode(_isoCode);
}
// Validate heartbeat
if(_heartbeat < MIN_HEARTBEAT || _heartbeat > MAX_HEARTBEAT)
revert InvalidHeartbeat(_heartbeat);
}
function requestMintWeatherNFT(
string memory _pincode,
string memory _isoCode,
bool _registerKeeper,
uint256 _heartbeat,
uint256 _initLinkDeposit
) external payable returns (bytes32 _reqId) {
validateInputs(_pincode, _isoCode, _heartbeat);
// ...existing code...
}
}

Alternative Implementation with Regex Support:

library InputValidator {
function validatePincode(string memory pincode) internal pure returns (bool) {
bytes memory b = bytes(pincode);
if(b.length != 6) return false;
for(uint i; i < b.length; i++) {
if(uint8(b[i]) < 48 || uint8(b[i]) > 57) return false;
}
return true;
}
function validateISOCode(string memory isoCode) internal pure returns (bool) {
bytes memory b = bytes(isoCode);
if(b.length != 2) return false;
for(uint i; i < b.length; i++) {
if(uint8(b[i]) < 65 || uint8(b[i]) > 90) return false;
}
return true;
}
}
Updates

Appeal created

bube Lead Judge 7 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

[Invalid] Lack of input validation in `requestMintWeatherNFT`

This is informational. It is user's responsibility to provide correct input arguments. If the user provides incorrect arguments, it will lead to incorrect results, lost funds or failed transaction.

Support

FAQs

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