T09 · Insecure Skill Coding Practices
- Location
scripts/go_stargazing_engine/weather.py:75- Finding
TLS Certificate Verification Disabled During Weather API Retries
- Content
View full analysis
dict: context = ssl._create_unverified_context() if insecure else None req = urllib.request.Request( url, headers={ "User-Agent": "go-stargazing/1.x (+Open-Meteo client)", "Accept": "application/json", }, ) with urllib.request.urlopen(req, timeout=30, context=context) as resp: return _extract_first_json_object(resp.read().decode("utf-8")) def fetch_openmeteo_payload(point: SamplePoint, target_dt: datetime, timezone: str, model: Optional[str] = None, max_retries: int = 2, retry_delay_s: float = 0.8) -> dict: # Query target date + next date, so the night window can include next-morning hours. end_date = (target_dt.date() + timedelta(days=1)).isoformat() params = { "latitude": point.lat, "longitude": point.lng, "hourly": "cloud_cover,relative_humidity_2m,visibility,wind_speed_10m,dew_point_2m,precipitation,cloud_base_height,weather_code", "timezone": timezone, "start_date": target_dt.date().isoformat(), "end_date": end_date, } if model and model != "best_match": params["models"] = model url = OPEN_METEO_FORECAST_URL + "?" + urllib.parse.urlencode(params) last_exc: Optional[Exception] = None total_attempts = max(1, max_retries + 1) for attempt in range(total_attempts): point.fetch_attempts = attempt + 1 insecure = attempt > 0 try: payload = _fetch_json_via_urllib(url, insecure=insecure) point.fetch_recovered = attempt > 0 point.fetch_error_type = None point.fetch_error_message = None return payload except Exception as exc: last ...[truncated 2475 chars]- Remediation
View remediation
dict: req = urllib.request.Request( url, headers={ "User-Agent": "go-stargazing/1.x (+Open-Meteo client)", "Accept": "application/json", }, ) with urllib.request.urlopen(req, timeout=30) as resp: return _extract_first_json_object(resp.read().decode("utf-8")) ``` 3. Preserve certificate and hostname verification during all retry attempts. 4. Treat TLS failures as hard failures rather than retrying with weaker security. 5. Retain bounded exponential backoff for transient timeout and server errors, but distinguish those conditions from certificate-validation errors. 6. If a custom trust store is required, construct a verified context using `ssl.create_default_context(cafile=...)` and maintain the CA bundle securely. 7. Add a regression test that replaces the endpoint with a server using an untrusted certificate and verifies that every attempt fails closed. 8. Consider validating the expected response schema before forecast values enter the scoring engine. ]]>
