T09 · Insecure Skill Coding Practices
- Location
scripts/search_flights.py:28- Finding
Predictable Shared Temporary Cache Enables Cache Poisoning and Symlink-Based File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/search_flights.py, lines 28-29 and 69-96
Vulnerability Type: Unsafe temporary-file handling
Risk Level: MediumVulnerable Code
python AIRLINES_CACHE = "/tmp/airlines_cache.json" AIRLINES_CACHE_TTL = 86400 # 24 часаpython def load_airlines(token: str) -> dict: """Загружает маппинг авиакомпаний с кэшированием.""" cache_path = Path(AIRLINES_CACHE) # Проверяем кэш if cache_path.exists(): age = time.time() - cache_path.stat().st_mtime if age < AIRLINES_CACHE_TTL: try: with open(cache_path, encoding="utf-8") as f: return json.load(f) except Exception: pass # Загружаем с API try: url = f"{BASE_URL}/data/ru/airlines.json" resp = requests.get(url, params={"token": token}, timeout=10) resp.raise_for_status() data = resp.json() # data — список объектов [{code, name, ...}] mapping = {} for item in data: code = item.get("code") or item.get("iata") name = item.get("name") or item.get("name_translations", {}).get("ru", "") if code and name: mapping[code] = name # Сохраняем кэш with open(cache_path, "w", encoding="utf-8") as f: json.dump(mapping, f, ensure_ascii=False) return mapping except Exception: # Возвращаем встроенный маппинг return AIRLINES_FALLBACKTechnical Analysis
The airline cache uses the fixed and globally predictable path
/tmp/airlines_cache.json. Shared temporary directories are normally writable by other local users. The implementation does not verify that the cache is a regular file owned by the current user, does not reject symbolic links, and does not use secure or atomic file-creation flags.The ...[truncated 2590 chars]
- Remediation
View remediation
Remediation Suggestions
- Store the cache in a private, per-user cache directory rather than directly under the shared
/tmpdirectory. Create the directory with permissions0700. - Create cache files with permissions
0600and reject symbolic links. On supported Unix systems, useos.open()withO_NOFOLLOW, appropriate creation flags, and an explicit mode. - Before reading an existing cache, use
lstat()or equivalent checks to confirm that it is a regular file, is not a symbolic link, and is owned by the current effective user. - Write updates to a securely created temporary file inside the private cache directory, flush and close it, and then atomically replace the cache with
os.replace(). - Validate cached JSON before use. Require a dictionary whose keys and values match expected airline-code and display-name formats, and impose reasonable size limits.
- Consider using
platformdirsto select an operating-system-appropriate per-user cache location ortempfilefor secure temporary-file creation. - Handle ownership or type-check failures by ignoring the unsafe cache rather than opening or replacing it.
- Store the cache in a private, per-user cache directory rather than directly under the shared
