Pentest 48.3 MEDIUM + 48.4 INFO: Rate-Limit + Token-Invalidierung beim Staff-Passwort-Reset
48.3 (Rate-Limit fehlt): POST /api/users/:id/password verlangt seit 47.3 die Eingabe des eigenen Admin-Passworts. Ohne Throttle könnte ein Angreifer mit gestohlenem JWT die Re-Auth per Brute-Force aushebeln. - Neuer staffPasswordReAuthLimiter (5 Versuche / 10 min, bucket: IP + target-user-id, skipSuccessfulRequests: true) - emit SecurityEvent RATE_LIMIT_HIT severity HIGH - Vor authenticate gemounted, damit auch unauth-Spamming begrenzt wird 48.4 (Alter Token überlebt Self-Reset): Nach erfolgreichem Setzen wird tokenInvalidatedAt des Ziel-Users auf jetzt gesetzt. Greift besonders bei Self-Reset (Admin setzt sich selbst zurück) – ein zuvor gestohlenes Token wird sofort ungültig, statt bis zum natürlichen Ablauf (15 min) brauchbar zu bleiben. Die bestehende Auth-Middleware liest tokenInvalidatedAt bereits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -241,10 +241,20 @@ export async function setUserPassword(req: Request, res: Response): Promise<void
|
||||
res.status(404).json({ success: false, error: 'Benutzer nicht gefunden' } as ApiResponse);
|
||||
return;
|
||||
}
|
||||
// Pentest 48.4 (INFO, 2026-06-01): Bestehende JWTs für den Ziel-User
|
||||
// sofort invalidieren. Greift insbesondere bei Self-Reset (Admin setzt
|
||||
// sich selbst zurück) – der gestohlene Token wird damit ungültig,
|
||||
// statt noch bis zum natürlichen Ablauf brauchbar zu bleiben.
|
||||
// Die Middleware-Auth liest tokenInvalidatedAt und vergleicht gegen
|
||||
// den `iat`-Claim des JWT.
|
||||
await prisma.user.update({
|
||||
where: { id: user.id },
|
||||
data: { tokenInvalidatedAt: new Date() },
|
||||
});
|
||||
await logChange({
|
||||
req, action: 'UPDATE', resourceType: 'User',
|
||||
resourceId: user.id.toString(),
|
||||
label: `Passwort für Benutzer ${user.firstName} ${user.lastName} (${user.email}) durch Admin gesetzt (Re-Auth bestätigt)`,
|
||||
label: `Passwort für Benutzer ${user.firstName} ${user.lastName} (${user.email}) durch Admin gesetzt (Re-Auth bestätigt, Sessions invalidiert)`,
|
||||
});
|
||||
res.json({ success: true, message: 'Passwort gesetzt' } as ApiResponse);
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user