Harden API security: input validation, safe auth extraction, new tests, and deploy config

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>
This commit is contained in:
Trey t
2026-03-02 09:48:01 -06:00
parent 56d6fa4514
commit 7690f07a2b
123 changed files with 8321 additions and 750 deletions

51
audit-digest-2.md Normal file
View File

@@ -0,0 +1,51 @@
# Digest 2: admin/handlers (remaining 15 files)
### admin/handlers/document_image_handler.go (245 lines)
- N+1: toResponse queries DB per image in List
- Same SortBy SQL injection
### admin/handlers/feature_benefit_handler.go (231 lines)
- `binding` tags instead of `validate` - required fields never enforced
### admin/handlers/limitations_handler.go (451 lines)
- Line 37: Unchecked Create error for default settings
- Line 191-197: UpdateTierLimits overwrites ALL fields even for partial updates
### admin/handlers/lookup_handler.go (877 lines)
- **CRITICAL**: Lines 30-32, 50-52, etc.: refreshXxxCache checks `if cache == nil {}` with EMPTY body, then calls cache.CacheXxx() — nil pointer panic when cache is nil
- Line 792: Hardcoded join table name "task_contractor_specialties"
### admin/handlers/notification_handler.go (419 lines)
- Line 351-363: HTML template built by string concatenation with user-provided subject/body — XSS in admin emails
### admin/handlers/notification_prefs_handler.go (347 lines)
- Line 154: Unchecked user lookup — deleted user produces zero-value username/email
### admin/handlers/onboarding_handler.go (343 lines)
- Line 304: Internal error details leaked to client
### admin/handlers/password_reset_code_handler.go (161 lines)
- **BUG**: Line 85: `code.ResetToken[:8] + "..." + code.ResetToken[len-4:]` panics if token < 8 chars
### admin/handlers/promotion_handler.go (304 lines)
- `binding` tags: required fields never enforced
### admin/handlers/residence_handler.go (371 lines)
- Lines 121-122: Unchecked Count errors for task/document counts
### admin/handlers/settings_handler.go (794 lines)
- Line 378: Raw SQL execution from seed files (no parameterization)
- Line 529-793: ClearAllData is destructive with no double-auth check
- Line 536-539: Panic in ClearAllData silently swallowed
### admin/handlers/share_code_handler.go (225 lines)
- Line 155-162: `IsActive` as non-pointer bool — absent field defaults to false, deactivating codes
### admin/handlers/subscription_handler.go (237 lines)
- **BUG**: Line 40-41: JOIN uses "users" but actual table is "auth_user" — query fails on PostgreSQL
### admin/handlers/task_handler.go (401 lines)
- Line 247-296: Admin Create bypasses service layer — no business logic applied
### admin/handlers/task_template_handler.go (347 lines)
- Lines 29-31: Same nil cache panic as lookup_handler.go