From 7f2785fb058305785592aec813eaaad8900c9218 Mon Sep 17 00:00:00 2001 From: Philipp Date: Thu, 21 May 2026 15:43:36 +0200 Subject: [PATCH] reloaded issues --- docs/fixes-todo.md | 83 +++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/docs/fixes-todo.md b/docs/fixes-todo.md index bd7b4d8..5a7efde 100644 --- a/docs/fixes-todo.md +++ b/docs/fixes-todo.md @@ -7,31 +7,27 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand ## 🔴 Kritisch — vor Produktion blockierend -- [ ] **1. Default-Admin `admin/admin` entfernen** - - Datei: `management/src/db.js:84`, `management/src/config.js:10` - - Aktuell: leeres `AUTH_PASSWORD` → Passwort wird still auf `"admin"` gesetzt. - - Fix: Bei leerem Passwort + leerer User-Tabelle Start mit klarer Fehlermeldung abbrechen. Keinen Default mehr in den Code. - - README/`docs/deployment.md` entsprechend anpassen. +- [x] **1. Default-Admin `admin/admin` entfernen** ✅ erledigt + - `management/src/db.js:83` — wirft jetzt Exception bei leerem `AUTH_PASSWORD`. Kein Silent-Fallback mehr. + - README/`docs/deployment.md` entsprechend anpassen (noch offen). -- [ ] **2. `API_TOKEN` im Node-Agent zur Pflicht machen** - - Datei: `backend/src/index.js:24`, `backend/src/config.js:19` - - Aktuell: `if (!config.apiToken) next();` → ohne Token offener Root-RCE-Endpunkt. - - Fix: Beim Start verweigern wenn leer. Minimal-Länge erzwingen (z.B. 32 Zeichen). +- [x] **2. `API_TOKEN` im Node-Agent zur Pflicht machen** ✅ erledigt + - `backend/src/config.js:44` — Start schlägt fehl wenn Token fehlt oder kürzer als 32 Zeichen. + - `backend/src/index.js` — `if (!config.apiToken) next()` entfernt; Token-Prüfung immer aktiv. -- [ ] **3. HTTPS zwischen Management und Agent erzwingen** - - Datei: `management/src/agentClient.js:2`, `management/src/routes/nodes.js:91` - - Aktuell: `node.baseUrl` darf beliebiges Schema haben, Bearer-Token läuft potenziell im Klartext. - - Fix: `baseUrl` muss `https://` sein (Validator). Optional: eigene CA + Cert-Pinning pro Node, mindestens dokumentieren. +- [x] **3. HTTPS zwischen Management und Agent erzwingen** ✅ erledigt + - `management/src/routes/nodes.js:102-112` — `validateBaseUrl` erzwingt `https://`. Escape-Hatch `ALLOW_INSECURE_AGENT_HTTP=true` nur für Dev. + - `management/src/agentClient.js` — eigene CA über `AGENT_CA_FILE` konfigurierbar. + - Agent-Server unterstützt TLS via `HTTPS_ENABLED`, `TLS_CERT_FILE`, `TLS_KEY_FILE`. -- [ ] **4. CSRF-Risiko durch reflektierendes CORS schließen** - - Datei: `management/src/index.js:18` - - Aktuell: `cors({ origin: true, credentials: true })` reflektiert jede Origin. - - Fix: Whitelist konkreter Frontend-Origins via Env. Cookie auf `SameSite=Strict` setzen oder CSRF-Token-Pattern (Double-Submit) ergänzen. +- [x] **4. CSRF-Risiko durch reflektierendes CORS schließen** ✅ erledigt + - `management/src/index.js:18-27` — Nur Origins aus `CORS_ORIGINS`-Env zugelassen. + - `management/src/auth.js:57` — Cookie auf `SameSite=Strict` gesetzt. -- [ ] **5. Brute-Force-Schutz beim Login** - - Datei: `management/src/routes/auth.js:12` - - Aktuell: kein Rate-Limit, kein Lockout. - - Fix: `express-rate-limit` o.ä. — z.B. 5 Versuche / 15 min / IP + User. Audit-Event für gesperrte Versuche. +- [x] **5. Brute-Force-Schutz beim Login** ✅ erledigt + - `management/src/routes/auth.js:7-9` — In-Memory Rate-Limit: 5 Versuche / 15 min / IP+User. + - Audit-Event `login_blocked` und `login_failed` implementiert. + - Hinweis: Kein externer `express-rate-limit` nötig, eigenständige Implementierung ausreichend. - [ ] **6. Restore atomarisieren — kein direktes `dd` auf Produktiv-Volume** - Datei: `backend/src/executor.js:92` (`streamResticDumpToDd`), `backend/src/routes/restore.js` @@ -49,18 +45,16 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand - Nach Restic-Commit `restic stats ` vergleichen. - Bei Mismatch oder Pipe-Fehler: Restic-Snapshot per ID `forget`+`prune`en, Job auf `failed`. -- [ ] **8. Bearer-Token aus Frontend-`localStorage` entfernen** - - Datei: `frontend/src/api.js:9` - - Aktuell: Agent-API-Token im Browser-Storage; bei XSS sofort kompromittiert. - - Fix: Frontend nutzt ausschließlich Cookie-Auth zum Management. `VITE_API_TOKEN`/`setApiToken` ersatzlos streichen. +- [x] **8. Bearer-Token aus Frontend-`localStorage` entfernen** ✅ erledigt + - `frontend/src/api.js` — nur noch Cookie-Auth (`withCredentials: true`). `localStorage`-Token und `VITE_API_TOKEN` entfernt. --- ## 🟠 Hoch -- [ ] **9. Session-Cookie `Secure`-Flag** - - Datei: `management/src/auth.js:37` - - Fix: `Secure` immer setzen (in Production hart erzwingen), Cookie-Attribute über Config konfigurierbar machen. +- [~] **9. Session-Cookie `Secure`-Flag** ⚠️ teilweise erledigt + - `management/src/auth.js:56` — `Secure`-Flag via `SESSION_COOKIE_SECURE` konfigurierbar, auto-aktiviert bei `NODE_ENV=production`. + - Offen: `management/.env.example` hat `SESSION_COOKIE_SECURE=false` — in Deployment-Doku explizit als "in Produktion auf `true` setzen" dokumentieren. - [ ] **10. Race beim Sichtbarmachen des Snapshot-Devices** - Datei: `backend/src/routes/backup.js:57` @@ -74,8 +68,8 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand - [ ] **12. Toten `SESSION_SECRET` aufräumen** - Datei: `management/src/config.js:8` - - Aktuell: gelesen, aber nirgendwo genutzt — sieht aus wie ein Loch. - - Fix: Entweder Session-IDs HMAC-signieren oder Variable entfernen + `.env.example` säubern. + - Aktuell: `SESSION_SECRET` wird geladen, aber nirgendwo genutzt — toter Code. + - Fix: Variable und zugehörigen `.env.example`-Eintrag entfernen, oder Session-IDs HMAC-signieren und Variable dann sinnvoll nutzen. - [ ] **13. Snapshot-ID-Prefix-Matching eindeutig machen** - Datei: `backend/src/validators.js:66` @@ -100,7 +94,8 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand ## 🟡 Mittel - [ ] **17. `Math.random()` durch `crypto.randomBytes` ersetzen** - - Datei: `management/src/db.js:90` (`cryptoId`). + - Datei: `management/src/db.js:93` (`cryptoId`). + - Noch vorhanden: `Math.random().toString(16)` für DB-interne User-IDs — kein akutes Sicherheitsproblem, aber nicht kryptografisch sicher. - [ ] **18. Systemd-Hardening für den Agent** - Datei: `deploy/systemd/incus-backup-agent.service` @@ -180,10 +175,24 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand --- -## Top-5 Sofort-Patches (Vorschlag Reihenfolge) +## Status-Übersicht kritische Punkte (Stand 2026-05-21) -1. #1 Default-Passwort entfernen + #2 `API_TOKEN` Pflicht. -2. #3 HTTPS-Pflicht für Agent-URL. -3. #4 CORS-Whitelist + #9 `Secure`-Cookie. -4. #5 Login-Rate-Limit. -5. #6/#7 Restore- und Backup-Verifikation (größter Aufwand, größter Impact auf Datenintegrität). +| # | Titel | Status | +|---|-------|--------| +| 1 | Default-Admin `admin/admin` entfernen | ✅ erledigt | +| 2 | `API_TOKEN` Pflicht | ✅ erledigt | +| 3 | HTTPS Management↔Agent | ✅ erledigt | +| 4 | CORS-Whitelist + SameSite=Strict | ✅ erledigt | +| 5 | Brute-Force-Schutz Login | ✅ erledigt | +| 6 | Restore atomarisieren | ⬜ offen | +| 7 | Backup-Verifikation | ⬜ offen | +| 8 | Bearer-Token aus localStorage | ✅ erledigt | +| 9 | Session-Cookie `Secure`-Flag | ⚠️ teilweise | + +## Nächste Prioritäten + +1. **#6/#7** Restore- und Backup-Verifikation — größter Aufwand, größter Impact auf Datenintegrität. +2. **#9** `SESSION_COOKIE_SECURE=true` in Deployment-Doku festschreiben. +3. **#12** Toten `SESSION_SECRET` entfernen. +4. **#15** ENV-Escaping vervollständigen (`$`, Backticks, Newlines). +5. **#11** Job- und Lock-Store auf SQLite persistieren (Crash-Sicherheit).