reloaded issues

This commit is contained in:
Philipp
2026-05-21 15:43:36 +02:00
parent e5bcce5dbb
commit 7f2785fb05
+46 -37
View File
@@ -7,31 +7,27 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand
## 🔴 Kritisch — vor Produktion blockierend ## 🔴 Kritisch — vor Produktion blockierend
- [ ] **1. Default-Admin `admin/admin` entfernen** - [x] **1. Default-Admin `admin/admin` entfernen** ✅ erledigt
- Datei: `management/src/db.js:84`, `management/src/config.js:10` - `management/src/db.js:83` — wirft jetzt Exception bei leerem `AUTH_PASSWORD`. Kein Silent-Fallback mehr.
- Aktuell: leeres `AUTH_PASSWORD` → Passwort wird still auf `"admin"` gesetzt. - README/`docs/deployment.md` entsprechend anpassen (noch offen).
- Fix: Bei leerem Passwort + leerer User-Tabelle Start mit klarer Fehlermeldung abbrechen. Keinen Default mehr in den Code.
- README/`docs/deployment.md` entsprechend anpassen.
- [ ] **2. `API_TOKEN` im Node-Agent zur Pflicht machen** - [x] **2. `API_TOKEN` im Node-Agent zur Pflicht machen** ✅ erledigt
- Datei: `backend/src/index.js:24`, `backend/src/config.js:19` - `backend/src/config.js:44` — Start schlägt fehl wenn Token fehlt oder kürzer als 32 Zeichen.
- Aktuell: `if (!config.apiToken) next();` → ohne Token offener Root-RCE-Endpunkt. - `backend/src/index.js` `if (!config.apiToken) next()` entfernt; Token-Prüfung immer aktiv.
- Fix: Beim Start verweigern wenn leer. Minimal-Länge erzwingen (z.B. 32 Zeichen).
- [ ] **3. HTTPS zwischen Management und Agent erzwingen** - [x] **3. HTTPS zwischen Management und Agent erzwingen** ✅ erledigt
- Datei: `management/src/agentClient.js:2`, `management/src/routes/nodes.js:91` - `management/src/routes/nodes.js:102-112` `validateBaseUrl` erzwingt `https://`. Escape-Hatch `ALLOW_INSECURE_AGENT_HTTP=true` nur für Dev.
- Aktuell: `node.baseUrl` darf beliebiges Schema haben, Bearer-Token läuft potenziell im Klartext. - `management/src/agentClient.js` — eigene CA über `AGENT_CA_FILE` konfigurierbar.
- Fix: `baseUrl` muss `https://` sein (Validator). Optional: eigene CA + Cert-Pinning pro Node, mindestens dokumentieren. - Agent-Server unterstützt TLS via `HTTPS_ENABLED`, `TLS_CERT_FILE`, `TLS_KEY_FILE`.
- [ ] **4. CSRF-Risiko durch reflektierendes CORS schließen** - [x] **4. CSRF-Risiko durch reflektierendes CORS schließen** ✅ erledigt
- Datei: `management/src/index.js:18` - `management/src/index.js:18-27` — Nur Origins aus `CORS_ORIGINS`-Env zugelassen.
- Aktuell: `cors({ origin: true, credentials: true })` reflektiert jede Origin. - `management/src/auth.js:57` — Cookie auf `SameSite=Strict` gesetzt.
- Fix: Whitelist konkreter Frontend-Origins via Env. Cookie auf `SameSite=Strict` setzen oder CSRF-Token-Pattern (Double-Submit) ergänzen.
- [ ] **5. Brute-Force-Schutz beim Login** - [x] **5. Brute-Force-Schutz beim Login** ✅ erledigt
- Datei: `management/src/routes/auth.js:12` - `management/src/routes/auth.js:7-9` — In-Memory Rate-Limit: 5 Versuche / 15 min / IP+User.
- Aktuell: kein Rate-Limit, kein Lockout. - Audit-Event `login_blocked` und `login_failed` implementiert.
- Fix: `express-rate-limit` o.ä. — z.B. 5 Versuche / 15 min / IP + User. Audit-Event für gesperrte Versuche. - Hinweis: Kein externer `express-rate-limit` nötig, eigenständige Implementierung ausreichend.
- [ ] **6. Restore atomarisieren — kein direktes `dd` auf Produktiv-Volume** - [ ] **6. Restore atomarisieren — kein direktes `dd` auf Produktiv-Volume**
- Datei: `backend/src/executor.js:92` (`streamResticDumpToDd`), `backend/src/routes/restore.js` - 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 <snapshotId>` vergleichen. - Nach Restic-Commit `restic stats <snapshotId>` vergleichen.
- Bei Mismatch oder Pipe-Fehler: Restic-Snapshot per ID `forget`+`prune`en, Job auf `failed`. - Bei Mismatch oder Pipe-Fehler: Restic-Snapshot per ID `forget`+`prune`en, Job auf `failed`.
- [ ] **8. Bearer-Token aus Frontend-`localStorage` entfernen** - [x] **8. Bearer-Token aus Frontend-`localStorage` entfernen** ✅ erledigt
- Datei: `frontend/src/api.js:9` - `frontend/src/api.js` — nur noch Cookie-Auth (`withCredentials: true`). `localStorage`-Token und `VITE_API_TOKEN` entfernt.
- 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.
--- ---
## 🟠 Hoch ## 🟠 Hoch
- [ ] **9. Session-Cookie `Secure`-Flag** - [~] **9. Session-Cookie `Secure`-Flag** ⚠️ teilweise erledigt
- Datei: `management/src/auth.js:37` - `management/src/auth.js:56``Secure`-Flag via `SESSION_COOKIE_SECURE` konfigurierbar, auto-aktiviert bei `NODE_ENV=production`.
- Fix: `Secure` immer setzen (in Production hart erzwingen), Cookie-Attribute über Config konfigurierbar machen. - 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** - [ ] **10. Race beim Sichtbarmachen des Snapshot-Devices**
- Datei: `backend/src/routes/backup.js:57` - 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** - [ ] **12. Toten `SESSION_SECRET` aufräumen**
- Datei: `management/src/config.js:8` - Datei: `management/src/config.js:8`
- Aktuell: gelesen, aber nirgendwo genutzt — sieht aus wie ein Loch. - Aktuell: `SESSION_SECRET` wird geladen, aber nirgendwo genutzt — toter Code.
- Fix: Entweder Session-IDs HMAC-signieren oder Variable entfernen + `.env.example` säubern. - 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** - [ ] **13. Snapshot-ID-Prefix-Matching eindeutig machen**
- Datei: `backend/src/validators.js:66` - Datei: `backend/src/validators.js:66`
@@ -100,7 +94,8 @@ Sortiert nach Risikoklasse. Datei-/Zeilenreferenzen beziehen sich auf den Stand
## 🟡 Mittel ## 🟡 Mittel
- [ ] **17. `Math.random()` durch `crypto.randomBytes` ersetzen** - [ ] **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** - [ ] **18. Systemd-Hardening für den Agent**
- Datei: `deploy/systemd/incus-backup-agent.service` - 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. | # | Titel | Status |
2. #3 HTTPS-Pflicht für Agent-URL. |---|-------|--------|
3. #4 CORS-Whitelist + #9 `Secure`-Cookie. | 1 | Default-Admin `admin/admin` entfernen | ✅ erledigt |
4. #5 Login-Rate-Limit. | 2 | `API_TOKEN` Pflicht | ✅ erledigt |
5. #6/#7 Restore- und Backup-Verifikation (größter Aufwand, größter Impact auf Datenintegrität). | 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).