Bei der Gegenprobe zur neuen Rolle "Gegenbuch" gefunden: Ein Konto mit ausschliesslich audit:read bekam auf GET /audit-logs/export eine 200. Die Berechtigung audit:export stand im Katalog und in der Rollenverwaltung - und wurde nirgends geprueft. Der Unterschied ist nicht kosmetisch. Blaettern zeigt 50 Zeilen; der Export liefert in einem Zug das gesamte Protokoll inklusive changesBefore und changesAfter, also der vollstaendigen Vorher/Nachher-Datensaetze, dazu resourceLabel mit Klartextnamen, IP-Adressen und User-Agents. Live nachgewiesen auf Staging: 43 Eintraege mit gefuellter resourceLabel allein fuer resourceType=Customer. Damit konnte ausgerechnet das Dienstkonto des Gegenbuchs Personendaten exportieren - das Konto, dessen Passwort im Klartext in der .env auf der Notar-Maschine liegt, und dem README und Rollenname "nur Pruefwerte lesen" zusichern. /audit-logs/export verlangt jetzt audit:export. Betroffen ist genau eine Rolle: Gegenbuch, und zwar gewollt. Die DSGVO-Rolle traegt audit:* vollstaendig und behaelt den Export. In der Oberflaeche erscheinen JSON- und CSV-Knopf nur noch mit audit:export - sonst stuenden dort Knoepfe, die zuverlaessig 403 liefern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
57 lines
2.5 KiB
TypeScript
57 lines
2.5 KiB
TypeScript
import { Router } from 'express';
|
||
import { authenticate, requirePermission } from '../middleware/auth.js';
|
||
import * as auditLogController from '../controllers/auditLog.controller.js';
|
||
|
||
const router = Router();
|
||
|
||
// Alle Routen erfordern Authentifizierung
|
||
router.use(authenticate);
|
||
|
||
// ACHTUNG Reihenfolge: Alle konkreten Pfade MÜSSEN vor der Parameter-Route
|
||
// '/:id' stehen, sonst schluckt diese sie und antwortet mit
|
||
// "Ungültige Audit-Log-ID". Genau so war GET /retention-policies unerreichbar
|
||
// (Pentest R166-04).
|
||
|
||
// Audit-Logs abrufen
|
||
router.get('/', requirePermission('audit:read'), auditLogController.getAuditLogs);
|
||
|
||
// Audit-Logs exportieren
|
||
//
|
||
// Verlangt `audit:export`, nicht `audit:read`. Die Berechtigung stand im
|
||
// Katalog und in der Rollenverwaltung, gatete aber NICHTS - jeder Leser
|
||
// konnte das vollstaendige Protokoll in einem Zug herausziehen.
|
||
//
|
||
// Das ist etwas anderes als Blaettern: Der Export liefert `changesBefore` und
|
||
// `changesAfter`, also die vollstaendigen Vorher/Nachher-Datensaetze, dazu
|
||
// `resourceLabel` mit Klartextnamen, IP-Adressen und User-Agents. Aufgefallen
|
||
// am Dienstkonto des Gegenbuchs: Es soll ausschliesslich Pruefwerte lesen -
|
||
// und konnte Personendaten exportieren.
|
||
router.get('/export', requirePermission('audit:export'), auditLogController.exportAuditLogs);
|
||
|
||
// Retention-Policies
|
||
router.get('/retention-policies', requirePermission('audit:admin'), auditLogController.getRetentionPolicies);
|
||
router.put('/retention-policies/:id', requirePermission('audit:admin'), auditLogController.updateRetentionPolicy);
|
||
|
||
// Kontrollwert für das externe Gegenbuch (nur lesend, ohne Geheimnisse)
|
||
router.get('/checkpoint', requirePermission('audit:read'), auditLogController.getCheckpoint);
|
||
|
||
// Audit-Logs für einen Kunden (DSGVO)
|
||
router.get('/customer/:customerId', requirePermission('audit:read'), auditLogController.getAuditLogsByCustomer);
|
||
|
||
// Hash-Ketten-Integrität prüfen
|
||
router.post('/verify', requirePermission('audit:read'), auditLogController.verifyIntegrity);
|
||
|
||
// Hash-Kette reparieren
|
||
router.post('/rehash', requirePermission('audit:admin'), auditLogController.rehashAll);
|
||
|
||
// Altbestand versiegeln (nicht destruktiv)
|
||
router.post('/seal-backlog', requirePermission('audit:admin'), auditLogController.sealBacklog);
|
||
|
||
// Retention-Cleanup manuell ausführen
|
||
router.post('/cleanup', requirePermission('audit:admin'), auditLogController.runRetentionCleanup);
|
||
|
||
// Einzelnes Audit-Log abrufen – als LETZTE GET-Route, siehe Hinweis oben
|
||
router.get('/:id', requirePermission('audit:read'), auditLogController.getAuditLogById);
|
||
|
||
export default router;
|