security-refactor-2026-05-14
tagged this
14 May 20:38
Markiert die zwei heutigen Commits, die zusammen ein umfassendes Security- und Stability-Refactor bilden. Auslöser war ein gründliches Multi-Agent-Code-Review des gesamten Repos. Abgedeckt in dieser Tag-Spanne (036d770 + 9faf8d5): Security - SSRF-Schutz: zentrale validate_external_url() in security.py (DNS-Resolve + Block auf private/loopback/reserved/link-local/ multicast/unspecified), durchgezogen in web_fetch, Web-Scraper, Scheduler-Webhook. - Path Traversal: Document-Upload (Filename-Sanitize + resolve-Check), Sandbox session_id (32-hex Whitelist), vision_utils Bild-Upload (uuid-Prefix statt race-y Sequential Counter), agent_bundle ZipSlip-Härtung mit _BUNDLE_FILE_RE + relative_to(). - API-Bind: backend_host auf 127.0.0.1 — /api/* nur noch über den nginx-Reverse-Proxy auf demselben Host erreichbar. - Passwort-Hash: bcrypt (cost=12) statt SHA-256 ohne Salt; alte SHA-256-Hashes werden bei erfolgreichem Login transparent re-hashed (hmac.compare_digest für Constant-Time-Vergleich). - Session-Authorization: delete_session enforced expected_owner. - OAuth-Callback: html.escape auf User-kontrollierten error/exc/ provider Strings. Stability - Stream-Retry: yielded_any-Guard in backends/base.py, lib/llm_pipeline.py und backends/ollama.py — keine Content- Duplikation mehr bei Mid-Stream-Errors, keine Re-Execution von Tools mit Side-Effects. - Scheduler-Session-ID auf 32-hex (matcht _sanitize_session_id) — geplante Jobs persistieren ihre Session jetzt tatsächlich. - switch_session ruft _restore_session auf → Active-Agent, Multi-Agent-Mode, Symposion-Agents, Research-Mode, Audio-State werden beim Session-Switch korrekt übernommen. - _backend_init_lock wird tatsächlich verwendet: globaler Init läuft komplett innerhalb des Locks (mit Re-Check), keine Doppel-Registrierung von Channel-Workern bei parallelen on_loads. - vector_cache._clear_sync rebaut die Collection mit der korrekten embedding_function — kein dimension-mismatch nach Clear mehr. - gpu_utils.get_model_size_from_cache walkt nur snapshots/ und dedupliziert Blobs per resolve() — keine 2×/N×-Doppelzählung von HF-Modellgrößen mehr. - process_utils.unload_all_gpu_models ruft vllm_manager._stop_sync direkt auf (statt asyncio.run_until_complete im laufenden Loop) — vLLM stoppt zuverlässig, kein VRAM-Leak bei Backend-Switch. Reflex-State-Reactivity - Alle in-place .append/Dict-Mutationen auf chat_history, llm_history, debug_messages, pending_images durch Reassignments ersetzt; nested Audio-Metadata-Updates rebuilden das Message-Dict komplett. Reflex erkannte In-Place-Mutationen vorher nicht zuverlässig → UI-Updates verspätet/fehlend. Bewusst nicht gefixt - Auto-Login-Cookie (LAN-Trust akzeptiert). - prompt_loader-Globals (kein konkreter Bug solange settings.json global ist; ContextVar-Refactor erst bei Per-User-Settings).