fix(SEC-29): Rollen-Trennung Admins/Auditoren, domain_auditor Rolle

- superadmin + domain_admin haben keinen Mail-Zugriff mehr (requireMailAccess)
- Neue Rolle domain_auditor: alle Tenant-Mails, kein Admin-Zugriff
- auditor + user: nur eigene Mails
- ZIP-Export: kein separates Attachment-Entpacken mehr, nur EML
- roleLevel() um domain_auditor (Level 3) erweitert

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-03-31 01:09:19 +02:00
parent e0f6a818eb
commit 64433aa847
5 changed files with 47 additions and 48 deletions
+18 -10
View File
@@ -34,14 +34,17 @@ func isValidMailID(id string) bool {
}
// roleLevel returns the privilege level for a role string.
// Hierarchy: superadmin=5 > admin=4 > domain_admin=3 > auditor=2 > user=1
// Hierarchy: superadmin=5 > domain_admin=4 > domain_auditor=3 > auditor=2 > user=1
// Separation of duties: admins (superadmin, domain_admin) have NO mail access.
// Mail access: domain_auditor (all tenant mails), auditor (own mails), user (own mails).
func roleLevel(role string) int {
levels := map[string]int{
userstore.RoleUser: 1,
userstore.RoleAuditor: 2,
userstore.RoleDomainAdmin: 3,
userstore.RoleAdmin: 4,
userstore.RoleSuperAdmin: 5,
userstore.RoleUser: 1,
userstore.RoleAuditor: 2,
userstore.RoleDomainAuditor: 3,
userstore.RoleDomainAdmin: 4,
userstore.RoleAdmin: 4, // legacy alias for domain_admin
userstore.RoleSuperAdmin: 5,
}
return levels[role]
}
@@ -261,10 +264,9 @@ func (s *Server) requireRole(role string, next http.HandlerFunc) http.HandlerFun
// ── Mail access middleware ────────────────────────────────────────────────
// requireMailAccess checks that the caller may read mail content.
// superadmin and domain_admin have read access (tenant-scoped via handleGetMail).
// Auditor and user have access to their own mails.
// The old "admin" role (now domain_admin) previously had no mail access — that
// restriction is removed; domain_admin now needs to be able to read archived mails.
// SEC-29: Strict separation of duties — admins manage, auditors review.
// Mail access is granted ONLY to: user, auditor, domain_auditor.
// superadmin and domain_admin are explicitly denied (manage system/tenant, not content).
func (s *Server) requireMailAccess(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sess := sessionFromCtx(r.Context())
@@ -272,6 +274,12 @@ func (s *Server) requireMailAccess(next http.HandlerFunc) http.HandlerFunc {
writeError(w, http.StatusUnauthorized, "not authenticated")
return
}
// SEC-29: Admins must not access mail content.
switch sess.Role {
case userstore.RoleSuperAdmin, userstore.RoleDomainAdmin:
writeError(w, http.StatusForbidden, "access denied")
return
}
next(w, r)
}
}