# Security Review (Public Launch Baseline) ## Purpose This document tracks launch-critical security findings for app, data, users, and host exposure, plus current mitigation status. ## Findings and Status 1. Direct home-IP exposure increases scanning and DDoS risk. - Status: Partially mitigated. - Mitigations in repo: - TLS + HTTPS redirect (apply via existing Nginx using `docker/nginx/fiddy.conf` template) - request rate limits (existing Nginx with `docker/nginx/fiddy.conf` template) - connection cap (existing Nginx with `docker/nginx/fiddy.conf` template) - Required ops actions: - enforce host firewall allowlist rules - restrict SSH to VPN or fixed allowlist - consider optional upstream shielding (Cloudflare free tier) 2. API abuse risk (auth and write endpoints). - Status: Mitigated. - Mitigations in repo: - server-side rate limiting (`apps/web/lib/server/rate-limit.ts`) - auth route limiter integration (`apps/web/app/api/auth/login/route.ts`, `apps/web/app/api/auth/register/route.ts`) - write-path limiter integration in server services (`apps/web/lib/server/*.ts`) - proxy rate limits (`docker/nginx/fiddy.conf`) 3. Sensitive log exposure risk. - Status: Mitigated. - Mitigations in repo: - invite/token/password redaction in error logging (`apps/web/lib/server/errors.ts`) - invite metadata stores last4 only (`apps/web/lib/server/groups.ts`, `apps/web/lib/server/group-invites.ts`) - removed client debug console output (`apps/web/components/tag-input.tsx`) 4. Request traceability gaps for incident response. - Status: Mitigated. - Mitigations in repo: - API response includes `request_id` + `requestId` compatibility alias - request-id propagation through proxy (`docker/nginx/includes/fiddy-proxy.conf`) - request-id response header (`docker/nginx/fiddy.conf`) - structured JSON access logging (`docker/nginx/fiddy.conf`) - nginx log ingestion by promtail (`docker/observability/promtail-config.yml`) 5. Session and auth contract risk. - Status: Mitigated. - Mitigations in repo: - DB-backed sessions with HttpOnly cookie use preserved (`apps/web/lib/server/session.ts`, auth routes) - route/service authorization remains server-side (`apps/web/lib/server/group-access.ts`, service modules) 6. Data leakage risk for receipt bytes. - Status: Mitigated. - Mitigations in repo: - entries list services do not return receipt bytes (`apps/web/lib/server/entries.ts`) - receipt bytes remain separate retrieval flow by contract ## Open Operational Tasks (Not Code) 1. Rotate all production secrets before public launch. 2. Run weekly restore drill and track measured RTO/RPO. 3. Enable host-level ban tooling (Fail2ban or CrowdSec) on nginx logs. 4. Create Grafana alerts for: - elevated 5xx rate - repeated 401/403 spikes - DB connectivity failures - disk usage thresholds ## Verification Checklist - [x] `npm run lint` passes (warnings acceptable for now). - [x] `npm test` passes. - [x] `npm run build` passes. - [ ] Production host firewall rules verified (`scripts/harden-host-ufw.sh` + `scripts/check-host-security.sh`). - [ ] SSH restricted to VPN/allowlist. - [ ] Backup restore drill logged for current week (`scripts/restore-drill-postgres.sh` + `scripts/log-restore-drill.sh`). - [ ] Base backup job configured and validated (`scripts/basebackup-postgres.sh`). - [ ] Auto-ban tooling configured (fail2ban or crowdsec) from `docker/security/`.