Harden user creation and password handling #89
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Local user authentication exists but lacks production-grade security. Passwords can be trivial, login is unbounded, and there's no self-service password management. The current implementation is vulnerable to brute-force attacks and allows weak credentials.
Current state
Implementation approach
Prefer existing libraries over rolling our own
Before implementing any of the below, research whether mature Spring/Java libraries already cover these concerns. Candidates to evaluate:
PasswordValidatorwith built-in rulesAuthenticationFailureHandler+ lockout support, or a servlet filter with GuavaCacheBuilderfor IP trackingLockedException+UserDetailsServicepattern, or a lightweight custom approach on top of our existinguserstablePick libraries that are actively maintained, have minimal transitive dependencies, and fit our existing Spring Boot 3.x / Spring Security 6.x stack. Only hand-roll what no library covers well.
Requirements
1. Password policy enforcement
Enforce on all password-setting paths (user creation, password change, admin reset):
2. Brute-force protection
POST /api/v1/auth/login— max 5 attempts per username per 15-minute windowfailed_login_attempts,locked_untilcolumns onusers)429 Too Many Requestswhen rate-limited (not 401, to distinguish from bad credentials)3. Password change endpoint
PUT /api/v1/auth/password— authenticated users change their own password:currentPasswordverification before accepting changenewPassword4. Admin password reset
PUT /api/v1/admin/users/{userId}/password— admin sets a new password for any user:5. Bootstrap admin hardening
6. Refresh token revocation
Required to support password changes and logout:
token_revoked_beforeTIMESTAMPTZ column tousers(default NULL)token_revoked_before = now()token_revoked_before7. OIDC users
localOut of scope
Acceptance criteria
Implemented in
827ba3c. Changes:PasswordPolicyValidator— min 12 chars, 3/4 character classes, rejects username matchfailed_login_attempts/locked_untilcolumns (V9 migration)token_revoked_beforecolumn, checked inJwtAuthenticationFilter, set on password changeoidcEnabledRemaining items for follow-up: IP-based rate limiting (in-memory, no DB), self-service password change endpoint (
PUT /api/v1/auth/password), bootstrap admin hardening (hash env var on first login).