# Password Security Hardening Plan ## Scope - Applies to auth and password flows in: - `index.js` - `auth/authEmail.js` - `mongoDB.js` ## 1. Replace insecure reset flow with token-based reset - Problem: - Current flow resets by username and emails a plaintext temporary password. - Implementation: - Add `POST /password/request-reset`: - Accept identifier (email). - Always return generic success response. - If account exists, create one-time reset token with short TTL (15-30 min), store hashed token, email reset link. - Add `POST /password/confirm-reset`: - Accept token + new password. - Validate token (exists, not expired, unused), then rotate password hash and invalidate all active sessions. - Data model: - New collection `password_reset_tokens` with fields: - `userId`, `tokenHash`, `expiresAt`, `usedAt`, `createdAt`, `requestMeta`. - Add TTL index on `expiresAt`. ## 2. Remove credential handling from GET/query - Problem: - `/signup` and `/login` accept GET and query params for credentials. - Implementation: - Change auth routes to `POST` only. - Read credentials from JSON body only. - Reject query-based credential inputs with `400`. - Update Swagger docs and clients accordingly. ## 3. Add account-aware brute-force protection - Problem: - Only global IP limiter exists; auth endpoints are not sufficiently protected. - Implementation: - Add dedicated limiter middleware for auth endpoints (`/login`, `/password/request-reset`, `/password/confirm-reset`): - Combined key: normalized username/email + source IP. - Lower thresholds and progressive backoff/lockout window. - Add telemetry for blocked attempts. - Optionally store counters in Redis if horizontally scaled. ## 4. Prevent account enumeration - Problem: - API exposes different responses for unknown user vs wrong password. - Implementation: - Login: same response for invalid credentials regardless of user existence. - Reset request: always same response regardless of account existence. - Keep detailed reason only in internal logs/analytics. ## 5. Keep strong password hashing policy (clarify bcrypt behavior) - Problem: - Existing TODO comments incorrectly state bcrypt needs manual salt handling. - Implementation: - Keep bcrypt (or migrate to Argon2id in a separate change set). - Centralize hash policy: - cost factor (benchmark-backed; start at 12 if acceptable latency). - minimum password length and strength checks. - On login, detect outdated hash params and rehash after successful auth. ## Suggested rollout order 1. Tokenized reset flow (new endpoints + DB token store). 2. POST-only auth route enforcement. 3. Generic auth/reset responses. 4. Dedicated auth rate limiting. 5. Hash policy tuning + opportunistic rehash. ## Validation checklist - Unit/integration tests: - reset token creation, expiry, one-time use, invalid token paths. - login generic error response behavior. - auth rate limiter trigger and cooldown. - query credential rejection. - Manual: - verify no plaintext password emails are sent. - verify existing sessions are revoked after password reset.