Pentest KRITISCH: Backup-Restore braucht Confirm-Body
POST /api/settings/backup/:name/restore startete bei leerem Body
sofort den destruktiven Restore. Im Unterschied zu /factory-reset
fehlte der Magic-String-Confirm-Check, sodass ein versehentlicher
Re-Fire (Doppelklick, Browser-Tab-Replay, eingeloggter Admin auf
bösartiger Drittseite) die komplette DB stillschweigend
überschreiben konnte.
Fix: gleicher Defensive-Pattern wie factoryReset – Body muss
{ "confirm": "RESTORE-BESTAETIGT" } enthalten, sonst 400. Der
Magic-String ist absichtlich ein einzigartiges Token (kein Boolean),
damit kein Auto-JSON-Tooling/Replay aus Versehen triggern kann.
Frontend-API-Client setzt das Token im Body automatisch – der
existierende Bestätigungs-Dialog im UI bleibt UX-mäßig unverändert.
Live-verifiziert:
- leerer Body → 400
- { confirm: "ja" } → 400
- { confirm: "RESTORE-BESTAETIGT" } → 200, Restore läuft
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -983,7 +983,13 @@ export const backupApi = {
|
||||
return res.data;
|
||||
},
|
||||
restore: async (name: string) => {
|
||||
const res = await api.post<ApiResponse<{ restoredRecords: number; restoredFiles: number }>>(`/settings/backup/${name}/restore`);
|
||||
// Server erzwingt confirm-Body als Schutz gegen versehentliche
|
||||
// Datenüberschreibung (Pentest 2026-05-19 KRITISCH, Analog zu
|
||||
// factoryReset). Der Confirm-String muss exakt dieser Wert sein.
|
||||
const res = await api.post<ApiResponse<{ restoredRecords: number; restoredFiles: number }>>(
|
||||
`/settings/backup/${name}/restore`,
|
||||
{ confirm: 'RESTORE-BESTAETIGT' },
|
||||
);
|
||||
return res.data;
|
||||
},
|
||||
delete: async (name: string) => {
|
||||
|
||||
Reference in New Issue
Block a user