fix(PROJ-61): Cross-Tenant Stored XSS via Mandanten-Logo behoben (Sicherheitsbug)

GET /api/tenants/{id}/logo prüfte nur die Authentifizierung, aber keinen
Tenant-Scope — jeder eingeloggte Nutzer konnte das Logo jedes beliebigen
Tenants lesen. Kombiniert mit dem bisher erlaubten SVG-Upload (kann
eingebettetes JavaScript enthalten) ergab das einen Cross-Tenant Stored-XSS:
ein domain_admin konnte ein bösartiges SVG als eigenes Logo hochladen und
Opfer aus beliebigen anderen Tenants per direktem Link darauf locken.

Fix: tenantAccessAllowed()-Scope-Check beim Logo-Lesepfad (analog PROJ-55),
SVG aus erlaubten Upload-Typen entfernt, X-Content-Type-Options: nosniff
als Defense-in-Depth ergänzt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sysops
2026-06-25 00:31:41 +02:00
co-authored by Claude Sonnet 4.6
parent 5f63bfe8d4
commit 363874767b
4 changed files with 73 additions and 9 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ func (s *Server) SetTenants(store *tenantstore.Store) {
s.mux.HandleFunc("DELETE /api/tenants/{id}/domains/{did}", s.authMiddleware(s.requireRole(userstore.RoleAdmin, s.handleRemoveTenantDomain)))
s.mux.HandleFunc("GET /api/tenants/{id}/users", s.authMiddleware(s.requireRole(userstore.RoleAdmin, s.handleListTenantUsers)))
// Logo routes: any auth can read; admin can write
// Logo routes: read is tenant-scoped inside handleGetTenantLogo (PROJ-61); admin can write
s.mux.HandleFunc("GET /api/tenants/{id}/logo", s.auth(s.handleGetTenantLogo))
s.mux.HandleFunc("POST /api/tenants/{id}/logo", s.authMiddleware(s.requireRole(userstore.RoleAdmin, s.handleUploadTenantLogo)))
s.mux.HandleFunc("DELETE /api/tenants/{id}/logo", s.authMiddleware(s.requireRole(userstore.RoleAdmin, s.handleDeleteTenantLogo)))