fix(security): demo sends nothing, hidden SMTP password, body limits (FLAW-33..38)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m52s

- Demo: senders for mail, Discord and webhooks refuse, no alarm ticker;
  test alarm, SMTP test, server settings, backups, account and session
  changes of the shared demo accounts answer 403; the session list only
  shows the own device. The UI shows the notices and disables the controls.
- SMTP password is never sent back (smtpPassSet), empty keeps it.
- ?token= on webhook ingest accepts only API keys.
- Request bodies capped at 2 MB (sync 8 MB, imports 101 MB).
- Deleting an account removes its server backups.
- Backup downloads, exports and import uploads get 30 minutes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-29 19:43:23 +01:00
1 parent 3709282a4f
commit 9d9698186c
21 files changed
+631 -304

No files matched your search

+18 -4
View File
@@ -246,6 +246,7 @@ func (s *Server) handleAdminDeleteUser(w http.ResponseWriter, r *http.Request) {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
s.removeUserBackups(targetUserID)
writeJSON(w, http.StatusOK, map[string]bool{"deleted": true})
}
@@ -302,8 +303,16 @@ func (s *Server) handleAdminGetSettings(w http.ResponseWriter, r *http.Request)
writeError(w, http.StatusInternalServerError, err.Error())
return
}
settings.SMTPConfiguredViaEnv = strings.TrimSpace(s.cfg.SMTPHost) != ""
writeJSON(w, http.StatusOK, settings)
writeJSON(w, http.StatusOK, s.settingsForBrowser(settings))
}
// settingsForBrowser hides the SMTP password; the admin only sees whether one is stored.
func (s *Server) settingsForBrowser(settings *domain.SystemSettings) *domain.SystemSettings {
out := *settings
out.SMTPPassSet = out.SMTPPass != ""
out.SMTPPass = ""
out.SMTPConfiguredViaEnv = strings.TrimSpace(s.cfg.SMTPHost) != ""
return &out
}
func (s *Server) handleAdminUpdateSettings(w http.ResponseWriter, r *http.Request) {
@@ -312,6 +321,12 @@ func (s *Server) handleAdminUpdateSettings(w http.ResponseWriter, r *http.Reques
writeError(w, http.StatusBadRequest, "Ungültiges JSON")
return
}
// Empty means unchanged (the browser never has it); without SMTP user the password goes too
if settings.SMTPPass == "" && strings.TrimSpace(settings.SMTPUser) != "" {
if cur, err := s.store.GetSystemSettings(); err == nil {
settings.SMTPPass = cur.SMTPPass
}
}
previousMode := s.store.SharingMode()
if err := s.store.UpdateSystemSettings(&settings); err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
@@ -324,8 +339,7 @@ func (s *Server) handleAdminUpdateSettings(w http.ResponseWriter, r *http.Reques
return
}
}
settings.SMTPConfiguredViaEnv = strings.TrimSpace(s.cfg.SMTPHost) != ""
writeJSON(w, http.StatusOK, settings)
writeJSON(w, http.StatusOK, s.settingsForBrowser(&settings))
}
func (s *Server) handleAdminTestSMTP(w http.ResponseWriter, r *http.Request) {