## Konkrete Findings - **Hoch – Neue Uploads sind über Legacy-Route ohne Authentifizierung abrufbar.** Der Worker registriert jedes importierte Original mit sequenzieller DB-ID und lokalem Pfad in `dokumente` (`scripts/health/health_dashboard_action_worker.py:1548-1559`). Die bestehende Route `/health-doc/` liefert diese Dateien ohne Principal-, Session- oder Review-Status-Prüfung aus (`scripts/health/health_dashboard_server.py:1301-1312`; Auflösung ohne Review-Filter: `385-399`). Damit wird die geschützte Upload-/V5-API-Grenze für neue, ungeprüfte Dokumente umgangen; numerische Enumeration genügt. - **Mittel – TOCTOU zwischen Validierung und tatsächlich importierten Bytes.** `validate_upload_file()` schließt den geprüften Descriptor, bevor PDF-Struktur/Seitenzahl bzw. Bilddekodierung erneut über den Pfad erfolgen (`scripts/health/dashboard_v5/document_review.py:108-143`). `load_quarantine()` validiert ebenfalls nur vorab und gibt danach einen Pfad zurück (`188-203`); der Worker öffnet diesen später neu und kopiert ihn ohne erneute Hash-/Magic-/Größenprüfung (`scripts/health/health_dashboard_action_worker.py:1510-1543`). Ein gleichprivilegierter lokaler Prozess kann die reguläre Datei zwischen diesen Schritten austauschen. - **Mittel – Quarantäne-Dateien bleiben bei voller/fehlgeschlagener Action Queue liegen.** Das Dokument wird zuerst vollständig in Quarantäne geschrieben (`scripts/health/health_dashboard_server.py:1471`), erst danach wird die begrenzte Queue befüllt (`1479`). Bei `QueueFullError` oder anschließendem `OSError` erfolgt keine Löschung des Quarantänepaares (`1483-1487`). Wiederholte authentifizierte Uploads von jeweils bis zu 20 MiB können dadurch den Datenträger füllen. - **Mittel – Extraktionsressourcen sind trotz Datei-/Seitenlimit nicht global begrenzt.** Bis zu 200 Seiten werden einzeln mit jeweils bis zu 60 Sekunden und unbeschränktem `capture_output` verarbeitet; OCR darf zusätzlich 600 Sekunden laufen, und extrahierter Text besitzt kein Gesamtgrößenlimit (`scripts/health/dashboard_v5/document_review.py:227-250`). Der Worker hat zwar `TimeoutStartSec=300`, aber kein `MemoryMax` (`deploy/systemd/health-dashboard-action-worker.service:20-31`). Stark komprimierte PDFs können daher RAM, temporären Speicher oder die Worker-Laufzeit erschöpfen. ## Positive Gates - Upload verlangt Browser-Session, exakten Same-Origin-Abgleich und einmaliges CSRF (`health_dashboard_server.py:1427-1447`). - Request- und dekodierte Dateigröße sind begrenzt; Base64 wird strikt validiert (`1452-1471`, `document_review.py:147-150`). - Magic-Bytes-Allowlist, PDF-Strukturprüfung und Seitenlimit `1..200`; Bilder werden tatsächlich dekodiert (`document_review.py:27-32,83-105,125-143`). - Zufällige Quarantäne-Tokens, feste Dateinamen, `0700/0600`, `O_EXCL`, `O_NOFOLLOW`, Hash-/Größenabgleich und Duplicate-Key-Rejection sind vorhanden. - API-Antworten einschließlich Fehlern und Original-Streaming setzen `no-store`, `nosniff` und restriktive Privacy-/CSP-Header. - Keine neuen externen HTTP-Requests; Extraktion erfolgt lokal. Worker läuft mit `PrivateNetwork=true` und `RestrictAddressFamilies=AF_UNIX`. - Fokus-Testlauf: **7/7 bestanden**; `git diff --check` sauber. **Änderungen:** keine Dateien erstellt oder verändert.