fix: configurable internal API URL and upload size enforcement
H4: add internal_api_base_url setting to config.py (default http://localhost:8888, env-overridable via INTERNAL_API_BASE_URL); replace all 5 hardcoded base_url strings in chat_service.py. H6: add post-read size check in both Excel and STEP upload handlers; raises HTTP 413 when content exceeds settings.max_upload_size_mb. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -534,6 +534,12 @@ Der Admin-Settings-Endpunkt (`GET /api/admin/settings`) erfordert `global_admin`
|
||||
### 2026-07-22 | Workflow-Editor | _legacy_dispatch umging cancelled/rejected Pre-Check
|
||||
`_legacy_dispatch` in `dispatch_service.py` rief `render_order_line_task.delay()` direkt auf und umging damit den Pre-Check in `dispatch_order_line_render` (der cancelled/rejected Lines überspringt). Alle Legacy-Dispatch-Pfade (auch im Graph-Fallback) liefen so durch, auch für bereits gecancelte Jobs. **Lösung:** `_legacy_dispatch` ruft jetzt `dispatch_order_line_render.delay()` auf statt `render_order_line_task.delay()` direkt.
|
||||
|
||||
### 2026-07-22 | Security | localhost:8888 hardcoded in chat_service.py
|
||||
`chat_service.py` verwendete `httpx.AsyncClient(base_url="http://localhost:8888", ...)` an 5 Stellen. In Docker löst `localhost` nicht zur Backend-Adresse auf, wenn der Service in einem anderen Container läuft. **Lösung:** `internal_api_base_url: str = "http://localhost:8888"` zu `config.py` Settings hinzugefügt (env-konfigurierbar via `INTERNAL_API_BASE_URL`). Alle 5 Stellen nutzen jetzt `settings.internal_api_base_url`.
|
||||
|
||||
### 2026-07-22 | Security | Upload-Größenlimit konfiguriert aber nie geprüft
|
||||
`settings.max_upload_size_mb` (Default 500 MB) existierte in `config.py`, wurde aber in beiden Upload-Handlern (`uploads.py`) nie gegen die tatsächliche Dateigröße geprüft. `file.read()` las beliebig große Dateien vollständig in den RAM. **Lösung:** POST-Read-Guard nach `content = await file.read()` in beiden Handlern — `len(content) > max_bytes` → HTTP 413.
|
||||
|
||||
### 2026-07-22 | Security | Billing-Rechnungen ohne Tenant-Isolation
|
||||
`list_invoices` in `billing/router.py` übergab `tenant_id` nicht an `get_invoices`. `get_invoices` im Service ignorierte den Parameter — kein WHERE-Filter vorhanden. Jeder `admin_or_pm`-User konnte alle Rechnungen aller Tenants sehen. **Lösung:** Router extrahiert `tenant_id` aus `current_user` (nur wenn nicht `global_admin`), Service filtert mit `.where(Invoice.tenant_id == tenant_id)`. `get_invoice_endpoint` prüft zusätzlich `inv.tenant_id == current_user.tenant_id` für Nicht-Admins.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user