--- id: PROJ-72 title: Fix Superadmin kann Passwort/Rolle von Superadmin-Peers nicht ändern (Sicherheitsbug) status: Deployed created: 2026-07-26 --- ## Problem `handleUpdateUser` (`internal/api/admin_users_handlers.go`) blockierte per SEC-01-Privilegien-Check (`roleLevel(target.Role) >= roleLevel(sess.Role)`) jede Modifikation an Ziel-Usern mit gleichem oder höherem Rollen-Level wie der Aufrufer. Da Superadmin das höchste Level ist (`roleLevel = 5`), traf dieser Vergleich auch Superadmin-vs-Superadmin zu: ein Superadmin konnte weder sich selbst noch andere Superadmins bearbeiten — u.a. kein Passwort-Reset für andere Superadmins möglich. ## Lösung Peer-Level-Check (`>=`-Vergleich für Ziel-Rolle und Rollen-Zuweisung) gilt nur noch für `sess.Role != userstore.RoleSuperAdmin`. Superadmin ist die höchste Stufe — es gibt keine höhere Rolle, vor der geschützt werden müsste, daher ist Superadmin von diesem Peer-Check ausgenommen. Zusätzlich: abgelehnte Privilege-Escalation-/Tenant-Isolation-Versuche (403) werden jetzt im Audit-Log als `Success: false` protokolliert (vorher nur erfolgreiche Updates geloggt) — Härtung, während QA-Verifikation entdeckt. ## Implementation Notes - `internal/api/admin_users_handlers.go` `handleUpdateUser`: - Peer-Level-Check (Ziel-Rolle + Rollen-Zuweisung) in `if sess.Role != userstore.RoleSuperAdmin { ... }` gekapselt. - Audit-Log-Eintrag (`Success: false`) bei: Cross-Tenant-Zugriff verweigert, Privilegien für Ziel-User-Modifikation fehlen, Privilegien für Rollen-Zuweisung fehlen. - `handleCreateUser`: Audit-Log-Eintrag (`Success: false`) bei verweigerter Rollen-Zuweisung beim Anlegen. - Tenant-Isolation-Check (SEC-02) unverändert — Superadmin hat `TenantID == nil`, überspringt diesen Block ohnehin. ## Acceptance Criteria - [x] Superadmin kann eigenes Passwort/Rolle/aktiv-Status ändern (Self-Patch). - [x] Superadmin kann Passwort/Rolle/aktiv-Status eines anderen Superadmins ändern (Peer-Patch). - [x] domain_admin kann weiterhin KEINE Peer- oder höherrangigen User (inkl. Superadmin) patchen (403). - [x] Cross-Tenant-Zugriff (IDOR) weiterhin blockiert (403). - [x] Kein Auth-Bypass (401 ohne gültigen Token). - [x] Abgelehnte Privilege-Escalation-Versuche erscheinen im Audit-Log (`Success: false`). ## QA Test Results (2026-07-27, gegen 192.168.1.132) | TC | Erwartung | Ergebnis | |---|---|---| | Superadmin patcht Peer-Superadmin (Rolle+Passwort+aktiv) | 200 | PASS | | Superadmin Self-Patch | 200 | PASS | | domain_admin patcht Superadmin (global) | 403 | PASS | | domain_admin patcht Peer-domain_admin (gleicher Tenant) | 403 | PASS | | domain_admin patcht User aus fremdem Tenant (IDOR) | 403 | PASS | | PATCH ohne JWT | 401 | PASS | | domain_admin weist eigenem Tenant-User Rolle "admin" zu | 403 | PASS | | domain_admin patcht regulären User im eigenen Tenant (Positivkontrolle) | 200 | PASS | Deployed auf 131 (Produktiv) und 132 (teilproduktiv) am 2026-07-26/27.