Fix weather satellite decoder security, architecture, and race conditions

Security: replace path traversal-vulnerable str().startswith() with
is_relative_to(), anchor path checks to app root, strip filesystem
paths from error responses, add decoder-level path validation.

Architecture: use safe_terminate/register_process for subprocess
lifecycle, replace custom SSE generator with sse_stream(), use
centralized validate_* functions, remove unused app.py declarations.

Bugs: add thread-safe singleton locks, protect _images list across
threads, move blocking process.wait() to async daemon thread, fix
timezone handling for tz-aware datetimes, use full path for image
deduplication, guard TLE auto-refresh during tests, validate
scheduler parameters to avoid 500 errors.

Docker: pin SatDump to v1.2.2 and slowrx to ca6d7012, document
INTERCEPT_IMAGE fallback pattern.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mitch Ross
2026-02-08 21:29:45 -05:00
parent 94ee22fdd4
commit 54c849ab60
7 changed files with 124 additions and 110 deletions

View File

@@ -31,6 +31,7 @@ ALLOWED_TLE_HOSTS = ['celestrak.org', 'celestrak.com', 'www.celestrak.org', 'www
_tle_cache = dict(TLE_SATELLITES)
# Auto-refresh TLEs from CelesTrak on startup (non-blocking)
import os
import threading
def _auto_refresh_tle():
@@ -42,7 +43,9 @@ def _auto_refresh_tle():
logger.warning(f"Auto TLE refresh failed: {e}")
# Delay import — refresh_tle_data is defined later in this module
threading.Timer(2.0, _auto_refresh_tle).start()
# Guard to avoid firing during tests
if not os.environ.get('TESTING'):
threading.Timer(2.0, _auto_refresh_tle).start()
def _fetch_iss_realtime(observer_lat: Optional[float] = None, observer_lon: Optional[float] = None) -> Optional[dict]: