Weather Witness

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

oversimplifies weather conditions

Root + Impact

Description

  • Describe the normal behavior in one or more sentences
    The code fetches weather data by calling OpenWeatherMap's API to get the Current Weather code, it assigns a single weather_enum by weather condition and returns it as a uint256 integer.

  • Explain the specific issue or problem in one or more sentences
    The code only evaluates the first weather condition and assigns the weather_enum based on that, ignoring any other additional weather conditions may be present. As a result, it will misrespresent weather.

// Root cause in the codebase with @> marks to highlight the relevant section
const weather_id = @>weatherResponse.data.weather[0].id;<@ // Only uses the first weather condition
const weather_id_x = parseInt(weather_id / 100);
let weather_enum = 0;
// ref: https://openweathermap.org/weather-conditions
// thunderstorm
if (weather_id_x === 2) weather_enum = 3;
// rain
else if (weather_id_x === 3 || weather_id_x === 5) weather_enum = 2;
// snow
else if (weather_id_x === 6) weather_enum = 5;
// clear
else if (weather_id === 800) weather_enum = 0;
// cloudy
else if (weather_id_x === 8) weather_enum = 1;
// windy
else weather_enum = 4; @> // Default return even if any other weather conditions exist <@

Risk

Likelihood: High

  • Reason 1:
    This will occur whenever the OpenWeatherMap API returns multiple weather conditions in the weather[].

  • Reason 2:
    It will occur whenever the first condition weather[0] does not match a clear case (such as "haze"), causeing the code to return to default windy.

Impact: Medium to High

  • Impact 1:
    User may receive inaccurate weather result, leading to a incorrect UI elements.

  • Impact 2:
    The system relys on incorrect weather-based code can lead to logical errors, bad decisions.

Proof of Concept

// Simulated response from OpenWeatherMap API
const weatherResponse = {
data: {
weather: [
{ id: 701, main: "Mist" }, // Unhandled -> will fall to 'windy'
{ id: 500, main: "Light Rain" }, // Should map to 'rain' (2)
{ id: 802, main: "Clouds" } // Should map to 'clouds' (1)
]
}
};
// Problematic logic from original code
const weather_id = weatherResponse.data.weather[0].id;
const weather_id_x = parseInt(weather_id / 100);
let weather_enum = 0;
if (weather_id_x === 2) weather_enum = 3;
else if (weather_id_x === 3 || weather_id_x === 5) weather_enum = 2;
else if (weather_id_x === 6) weather_enum = 5;
else if (weather_id === 800) weather_enum = 0;
else if (weather_id_x === 8) weather_enum = 1;
else weather_enum = 4; // fallback
console.log("Assigned weather_enum:", weather_enum); // Incorrect Outputs: 4 ("windy"), ignoring rain and clouds

Recommended Mitigation

- const weather_id = weatherResponse.data.weather[0].id;
- const weather_id_x = parseInt(weather_id / 100);
-
- let weather_enum = 0;
-
- if (weather_id_x === 2) weather_enum = 3;
- else if (weather_id_x === 3 || weather_id_x === 5) weather_enum = 2;
- else if (weather_id_x === 6) weather_enum = 5;
- else if (weather_id === 800) weather_enum = 0;
- else if (weather_id_x === 8) weather_enum = 1;
- else weather_enum = 4;
+ const weatherConditions = weatherResponse.data.weather;
+ let weather_enum = 4; // Default: windy or undefined
+
+ for (const condition of weatherConditions) {
+ const id = condition.id;
+ const category = Math.floor(id / 100);
+
+ if (id === 800) {
+ weather_enum = 0; // clear
+ break;
+ } else if (category === 2) {
+ weather_enum = 3; // thunderstorm
+ } else if (category === 3 || category === 5) {
+ weather_enum = Math.min(weather_enum, 2); // rain
+ } else if (category === 6) {
+ weather_enum = Math.min(weather_enum, 5); // snow
+ } else if (category === 8) {
+ weather_enum = Math.min(weather_enum, 1); // clouds
+ }
+ }
Updates

Appeal created

bube Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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