Files
honeyDueAPI/audit-digest-7.md
Trey t 7690f07a2b 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>
2026-03-02 09:48:01 -06:00

58 lines
2.6 KiB
Markdown

# Digest 7: monitoring/writer, notifications, push, repositories
### monitoring/writer.go (96 lines)
- Line 90-92: Unbounded fire-and-forget goroutines for Redis push — no rate limiting
### notifications/reminder_config.go (64 lines) - Clean config data
### notifications/reminder_schedule.go (199 lines)
- Line 112: Integer truncation of float division — DST off-by-one possible
- Line 148-161: Custom itoa reimplements strconv.Itoa
### push/apns.go (209 lines)
- Line 44: Double-negative logic — both Production=false and Sandbox=false defaults to production
### push/client.go (158 lines)
- Line 89-105: SendToAll last-error-wins — cannot tell which platform failed
- Line 150-157: HealthCheck always returns nil — useless health check
### push/fcm.go (140 lines)
- Line 16: Legacy FCM HTTP API (deprecated by Google)
- Line 119-126: If FCM returns fewer results than tokens, index out of bounds panic
### repositories/admin_repo.go (108 lines)
- Line 92: Negative page produces negative offset
### repositories/contractor_repo.go (166 lines)
- **RACE**: Line 89-101: ToggleFavorite read-then-write without transaction
- Line 91: ToggleFavorite doesn't filter is_active — can toggle deleted contractors
### repositories/document_repo.go (201 lines)
- Line 92: LIKE wildcards in user input not escaped
- Line 12: DocumentFilter.ResidenceID field defined but never used
### repositories/notification_repo.go (267 lines)
- **RACE**: Line 137-161: GetOrCreatePreferences race — concurrent calls both create, duplicate key error
- Line 143: Uses == instead of errors.Is for ErrRecordNotFound
### repositories/reminder_repo.go (126 lines)
- Line 115-122: rows.Err() not checked after iteration loop
### repositories/residence_repo.go (344 lines)
- Line 272: DeactivateShareCode error silently ignored
- Line 298-301: Count error unchecked in generateUniqueCode — potential duplicate codes
- Line 125-128: PostgreSQL-specific ON CONFLICT — fails on SQLite in tests
### repositories/subscription_repo.go (257 lines)
- **RACE**: Line 40: GetOrCreate race condition (same as notification_repo)
- Line 66: GORM v1 pattern `gorm:query_option` for FOR UPDATE — may not work in GORM v2
- Line 129: LIKE search on receipt data blobs — inefficient, no index
- Lines 40, 168, 196: Uses == instead of errors.Is
### repositories/task_repo.go (765 lines)
- Line 707-709: DeleteCompletion ignores image deletion error
- Line 62-101: applyFilterOptions applies NO scope when no filter set — could query all tasks
### repositories/task_template_repo.go (124 lines)
- Line 48: LIKE wildcard escape issue
- Line 79-81: Save without Omit could corrupt Category/Frequency lookup data