e17b9c9e56
Check Cross-Plugin Imports / check (push) Has been cancelled
- Add OwnedMixin to 15 models (contact_folder, user_preference, workspace, mcp_server_config, agent_definition, automation_definition, report_template, report_instance, entity_link, comm_conversation, proactive_suggestion, ai_agent, ai_chat_session, tag, share_link) - Migration 0102: Add owner_id column to 15 tables with backfill from user_id - Fix EntityPermission Registry: remove notification, add entity_attachment, entity_history, subtask, calendar, folder; fix wrong class names (DmsFile→File, CalendarEvent→CalendarEntry, Mailbox→MailAccount) - Add apply_visibility_filter to list endpoints in tags, tasks, mcp_client, automation, report_generator, ai_assistant routes - Add owner_id to create handlers for all new OwnedMixin models - Patch tasks/services.py and automation/services.py list methods with user_id and is_system_admin parameters
7.6 KiB
7.6 KiB
LeoCRM Security Fix Plan
Phase 1 — Kritische Sicherheitslücken (~8h)
1.1 ✅ 59 Permissions im Registry ergänzen
- 98 Permissions in Routes verwendet, nur 39 in CORE_PERMISSIONS
- Fehlend: ai:read, ai:write, automation:admin, mcp:read, mcp:write, calendar:read, dms:read, mail:read, tasks:read, tags:read, reports:read, search:read, agents:read, permissions:delegations:read, etc.
- Status: Implementiert und committed
1.2 ✅ Grants einschränken (Migration 0100)
- crm_api und crm_worker haben DELETE auf 12 sensitiven Tabellen: api_tokens, audit_log, notification_types, password_reset_tokens, plugin_allowlist, plugin_migrations, plugins, sessions, tenant_plugin_activation, tenants, user_tenants, users
- Fix: DELETE für crm_api und crm_worker auf diesen Tabellen entfernen
- crm_auth behält DELETE auf sessions + password_reset_tokens (für Logout/Reset)
- Status: Migration erstellt und committed
1.3 ❌ RLS auf Tabellen — ENTFERNT
- RLS auf sessions, password_reset_tokens, api_tokens, sequences, tenant_plugin_activation, user_tenants
- PROBLEM: Diese Tabellen werden vor/ohne Tenant-Context abgefragt → RLS blockiert Login/App-Startup
- WICHTIG: Kein RLS auf Tabellen die den Login blockieren!
- Status: Komplett aus Migration entfernt. Tabellen haben kein RLS wie vor der Änderung
1.4 ✅ Mass-Assignment Schutz
- UserCreate.role war setzbar (default viewer aber Client konnte admin senden)
- UserUpdate.role war setzbar
- Fix: UserCreate role=admin nur für is_system_admin. UserUpdate role=admin nur für is_system_admin
- Status: Implementiert und committed
1.5 ✅ Entity Permission Ownership-Check (PUT)
- PUT /permissions/{type}/{id}/{pid} hatte keinen Ownership-Check
- DELETE hatte einen Check
- Fix: _check_entity_ownership Hilfsfunktion, in PUT ergänzt
- Status: Implementiert und committed
1.6 ✅ AttachmentResponse file_path entfernt
- file_path: str in Schema Zeile 13 exponiert internen Storage-Pfad
- Fix: Aus Schema entfernt
- Status: Implementiert und committed
1.7 ✅ SystemSettings sensible Felder maskiert
- tax_number, iban, bic in Response Schema für alle sichtbar
- Fix: Für non-admin User maskiert ("********")
- Status: Implementiert und committed
1.8 ✅ File Upload MIME-Validierung + Extensions
- Nur Extension-Blocklist (ohne .php, .py, .asp, .jsp, .svg) + client-seitiger content_type (fälschbar)
- Fix: BLOCKED_EXTENSIONS ergänzt (.php, .py, .pl, .asp, .aspx, .jsp, .svg, .htaccess, .phtml, .pht, .cgi, .cfm, .erb) + ALLOWED_MIME_PREFIXES Whitelist + MIME-Validierung in upload_file
- Status: Implementiert und committed
Phase 2 — Visibility Filter & Owner ID (~12h)
2.1 Visibility Filter in 17 Services einbauen
- ai_assistant, ai_proactive, automation, entity_links, kommunikation, mail, mcp_client, permissions, report_generator, tags, tasks, entity_permission_service, user_service, workspace_service
- apply_visibility_filter funktioniert korrekt (tenant_id + owner_id + shared permissions + admin bypass)
2.2 owner_id auf 26 Modellen ergänzen
- Core (15): auth, contact_folder, contact_folder_permission, contact_merge, currency, entity_policy, group, guest_user, outbox, plugin, system_settings, tax, user, user_preference, workspace
- Plugins (11): mcp_client, automation, unified_search, report_generator, entity_links, kommunikation, ai_proactive, ai_assistant, tags, permissions
2.3 EntityPermission Registry korrigieren
- notification, contact_folder entfernen (kein owner_id)
- entity_attachment, entity_history, subtask, calendar, folder hinzufügen
Phase 3 — Weitere Sicherheitslücken (~4h)
3.1 WebSocket CSRF implementieren
- Kommentar sagt "skip CSRF for now" — nicht implementiert
- Fix: CSRF-Token aus Query-Parameter validieren
3.2 SameSite auf Lax
- session_cookie_samesite = "strict" blockiert WebSocket
- Fix: Auf "lax" ändern
3.3 Tenant FK CASCADE
- 3 Tabellen ohne CASCADE (contact_merge_history, tenant_plugin_activation, user_tenants)
- 10 Tabellen mit tenant_id aber ohne FK
- Fix: CASCADE ergänzen, fehlende FKs hinzufügen
Phase 4 — Krisensicherheit (~9h)
4.1 Redis Fallback / Graceful Degradation
- Bei Redis-Ausfall funktioniert nichts mehr
- Fix: Session-Check → DB-Fallback, Permission-Cache → DB-Fallback, Rate-Limiting → in-memory Fallback
4.2 DB-Connection Retry
- Bei kurzem DB-Ausfall gibt es sofort 500er
- Fix: Retry-Decorator (3 Versuche), 503 statt 500
4.3 Circuit Breaker Middleware
- Bei wiederholten Fehlern kein automatisches Fallback
- Fix: Bei 5 Fehlern in 30s → Circuit öffnet → 503 für 60s → Half-Open → probieren
Phase 5 — Architektur-Lücken (~40h)
5.1 Öffentliche Plugin-Endpoints
- Alle Plugin-Routes erfordern Auth
- Fix: get_public_routes() Mechanismus, separate Router-Mountung ohne Auth-Dependency
5.2 PWA aktivieren
- Dateien da aber Vite Plugin nicht konfiguriert
- Fix: vite-plugin-pwa installieren + konfigurieren, manifest.json, Service Worker
5.3 Contacts embedding + Auto-Index
- contacts hat KEINE embedding column — wichtigste Tabelle kann nicht semantisch suchen
- Fix: Migration: ADD COLUMN embedding vector(768), CREATE INDEX, Auto-Indexierung
5.4 Search Engine: alle Tabellen abdecken
- Nur 5 Tabellen in Suche (contacts, mails, files, calendar_entries, comm_messages)
- Fehlend: tasks, contactpersons, tags, comm_conversations, calendars, users, workflows, automation_runs, resources, ai_chat_sessions
5.5 Plugin-Marketplace
- Grundlage da (discover_external, plugin_allowlist, install from ZIP)
- Fehlend: Echter Marketplace-Server, Plugin-Signatur-Verifikation, Plugin-Versionierung, UI
5.6 Agent Memory (persistent)
- Kein persistentes Agent Memory (nur Session-History)
- Fix: agent_memories Tabelle mit embeddings, semantische Suche bei neuen Konversationen
5.7 GraphRAG als Provider
- Keine Graph-Struktur in DB oder Code
- Fix: entity_relationships Tabelle, Graph-Traversal, als Provider in unified_search
5.8 Subagents / Multi-Agent
- Keine Subagents, keine Multi-Agent-Orchestrierung
- automation/agent_comm.py hat Messaging-Infrastruktur
- Fix: Agent kann Agent aufrufen, Agent-Coordinator
5.9 Agent von außen erreichbar
- Agent nur über WebUI erreichbar
- Fix: API-Endpoint für externen Agent-Zugriff
Verifizierte Fakten
| Punkt | Ergebnis |
|---|---|
| 59 Permissions fehlen im Registry | ✅ Bestätigt |
| crm_api + crm_worker DELETE auf 12 Tabellen | ✅ Bestätigt |
| 5 Tabellen mit tenant_id aber ohne RLS | ✅ Bestätigt |
| UserCreate.role setzbar | ✅ Bestätigt |
| UserUpdate.role setzbar | ✅ Bestätigt |
| PUT Entity Permission ohne Ownership-Check | ✅ Bestätigt |
| AttachmentResponse.file_path exponiert | ✅ Bestätigt |
| SystemSettings exponiert IBAN/BIC/Steuernummer | ✅ Bestätigt |
| SameSite = strict | ✅ Bestätigt |
| 17 Services ohne Visibility Filter | ✅ Bestätigt |
| 26 Modelle ohne owner_id | ✅ Bestätigt |
| WebSocket CSRF nicht implementiert | ✅ Bestätigt |
| File Upload ohne echte MIME-Validierung | ✅ Bestätigt |
| .env nicht in Git | ✅ Bereits gefixt |
| password_reset_tokens RLS qual=true | ❌ War falsch — Tabelle hatte kein RLS |
| DELETE Entity Permission ohne Ownership | ❌ War falsch — DELETE hat Check |
WICHTIGE REGELN
- KEIN manuelles Rumgepfusche auf der Produktions-DB
- KEIN RLS auf Tabellen die den Login blockieren (sessions, password_reset_tokens, api_tokens, user_tenants, sequences, tenant_plugin_activation)
- Deploy NUR über Coolify Tool (deploy_start)
- Bei Deploy-Fehlern: Coolify DB nach Logs queryen, nicht manuell eingreifen
- Login-Logik NIEMALS ändern