Security [MEDIUM]: Password-policy client/server divergence + weak secret-entropy check #56
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
(1) Client validator uses
.length < 8but server enforces.min(12)— external API consumers could enforce weaker policy. (2)DISALLOWED_PRODUCTION_SECRETSblacklists only 5 strings (dev-secret-...,changeme, ...); a secret likepassword123passes. No minimum-entropy or length check for AUTH_SECRET.Evidence
apps/web/src/app/auth/reset-password/[token]/page.tsx:24 — password.length < 8packages/api/src/router/auth.ts:77 — .min(12)apps/web/src/server/runtime-env.ts:1-7 — 5-string blacklist, no entropy checkImpact
(1) Inconsistent UX/policy; external clients may enforce weaker. (2) Weak-but-not-blacklisted AUTH_SECRET accepted in production.
Proposed Fix
(1) Align client validator to
.length >= 12. Add character-class rules per NIST 800-63B (optional). Breach-check via HIBP k-anonymity API. (2) AUTH_SECRET minimum: ≥ 32 bytes base64 + entropy check (Shannon ≥ 4 bits/char). Document rotation process in docs/security-architecture.md.Acceptance Criteria
Parent Epic: #1
Source: Full-Codebase Security Audit 2026-04-16 (A-17, A-20)
Fixed on branch
security/audit-2026-04-17(commit01c45d0).What changed
1. Client/server password policy aligned
New shared constants in
@capakraken/shared:PASSWORD_MIN_LENGTH = 12PASSWORD_MAX_LENGTH = 128PASSWORD_POLICY_MESSAGEUpdated to import from the shared source:
SetupClient.tsx,reset-password/[token]/page.tsx,invite/[token]/page.tsx,UserCreateModal.tsx,setup/actions.tsrouter/auth.ts,router/invite.ts,router/user-procedure-support.tsminLengthandplaceholderattributes on the three public password forms so users see the correct threshold up-front.Drift now fails at compile time (missing import / wrong constant) rather than at runtime.
2.
AUTH_SECRETlength + entropy checkapps/web/src/server/runtime-env.tsnow adds two additional checks on top of the existing placeholder blacklist:openssl rand -base64 32output)aaaaaaaaaaa...)Two new unit tests cover both cases.
3. Rotation documented
Added a
#### Secret rotationsubsection todocs/security-architecture.md§3 describing:openssl rand -base64 32)POSTGRES_PASSWORDrotation pointer to the deployment runbookOut of scope / deliberate decisions
Verification
pnpm test:unit— 396 files / 1922 tests passedpnpm --filter @capakraken/web exec tsc --noEmit— cleanpnpm --filter @capakraken/api exec tsc --noEmit— cleanAcceptance criteria
docs/security-architecture.md§3