Comprehensive security hardening from audit findings: - Add validation tags to all DTO request structs (max lengths, ranges, enums) - Replace unsafe type assertions with MustGetAuthUser helper across all handlers - Remove query-param token auth from admin middleware (prevents URL token leakage) - Add request validation calls in handlers that were missing c.Validate() - Remove goroutines in handlers (timezone update now synchronous) - Add sanitize middleware and path traversal protection (path_utils) - Stop resetting admin passwords on migration restart - Warn on well-known default SECRET_KEY - Add ~30 new test files covering security regressions, auth safety, repos, and services - Add deploy/ config, audit digests, and AUDIT_FINDINGS documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.6 KiB
2.6 KiB
Digest 9: services (remaining), task package, testutil, validator, worker, pkg
services/storage_service.go (184 lines)
- Line 75: UUID truncated to 8 chars — increased collision risk
- SECURITY: Line 137-138: filepath.Abs errors ignored — path traversal check could be bypassed
services/subscription_service.go (659 lines)
- PERFORMANCE: Line 186-204: N+1 queries in getUserUsage — 3 queries per residence
- SECURITY/BUSINESS: Line 371: Apple validation failure grants 1-month free Pro
- SECURITY/BUSINESS: Line 381: Apple validation not configured grants 1-year free Pro
- SECURITY/BUSINESS: Line 429, 449: Same for Google — errors/misconfiguration grant free Pro
- Line 7: Uses stdlib "log" instead of zerolog
services/task_button_types.go (85 lines) - Clean, uses predicates correctly
services/task_service.go (1092 lines)
- DATA INTEGRITY: Line 601: If task update fails after completion creation, error only logged not returned — stale NextDueDate/InProgress
- Line 735: Goroutine in QuickComplete (service method) — inconsistent with synchronous CreateCompletion
- Line 773: Unbounded goroutine creation per user for notifications
- Line 790: Fail-open email notification on error (intentional but risky)
- SECURITY: Line 857-862: resolveImageFilePath has NO path traversal validation
services/task_template_service.go (70 lines) - Errors returned raw (not wrapped with apperrors)
services/user_service.go (88 lines) - Returns nil instead of empty slice (JSON null vs [])
task/categorization/chain.go (359 lines) - Clean chain-of-responsibility
task/predicates/predicates.go (217 lines)
- Line 210: IsRecurring requires Frequency preloaded — returns false without it
task/scopes/scopes.go (270 lines)
- Line 118: ScopeOverdue doesn't exclude InProgress — differs from categorization chain
task/task.go (261 lines) - Clean facade re-exports
testutil/testutil.go (359 lines)
- Line 86: json.Marshal error ignored in MakeRequest
- Line 92: http.NewRequest error ignored
validator/validator.go (103 lines) - Clean
worker/jobs/email_jobs.go (118 lines) - Clean
worker/jobs/handler.go (810 lines)
- Lines 95-106, 193-204: Direct DB access bypasses repository layer
- Line 627-635: Raw SQL with fmt.Sprintf (not currently user-supplied but fragile)
- Line 154, 251: O(N*M) lookup instead of map
worker/scheduler.go (240 lines)
- Line 200-212: Cron schedules at fixed UTC times may conflict with smart reminder system — potential duplicate notifications