5d21574c81
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>
30 lines
1.8 KiB
TypeScript
30 lines
1.8 KiB
TypeScript
import { Router } from 'express';
|
||
import * as userController from '../controllers/user.controller.js';
|
||
import { authenticate, requirePermission } from '../middleware/auth.js';
|
||
import { staffPasswordReAuthLimiter } from '../middleware/rateLimit.js';
|
||
|
||
const router = Router();
|
||
|
||
// Users (Admin only)
|
||
router.get('/', authenticate, requirePermission('users:read'), userController.getUsers);
|
||
router.post('/', authenticate, requirePermission('users:create'), userController.createUser);
|
||
router.get('/:id', authenticate, requirePermission('users:read'), userController.getUser);
|
||
router.put('/:id', authenticate, requirePermission('users:update'), userController.updateUser);
|
||
router.delete('/:id', authenticate, requirePermission('users:delete'), userController.deleteUser);
|
||
// Passwort-Reset durch Admin – dedizierter Endpoint (Pentest Runde 12).
|
||
// 47.3 verlangt Re-Auth (currentPassword), 48.3 wirft einen Rate-Limit
|
||
// davor, damit ein gestohlener JWT das Admin-Passwort nicht brute-forcen kann.
|
||
router.post('/:id/password', staffPasswordReAuthLimiter, authenticate, requirePermission('users:update'), userController.setUserPassword);
|
||
|
||
// Roles
|
||
router.get('/roles/list', authenticate, requirePermission('users:read'), userController.getRoles);
|
||
router.post('/roles', authenticate, requirePermission('users:create'), userController.createRole);
|
||
router.get('/roles/:id', authenticate, requirePermission('users:read'), userController.getRole);
|
||
router.put('/roles/:id', authenticate, requirePermission('users:update'), userController.updateRole);
|
||
router.delete('/roles/:id', authenticate, requirePermission('users:delete'), userController.deleteRole);
|
||
|
||
// Permissions
|
||
router.get('/permissions/list', authenticate, requirePermission('users:read'), userController.getPermissions);
|
||
|
||
export default router;
|