Files
opencrm/backend/src/routes/user.routes.ts
T
duffyduck 5d21574c81 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>
2026-06-01 13:01:44 +02:00

30 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;