Password requirements enforced
Why it matters
Weak password requirements are the primary enabler of credential-stuffing attacks: attackers replay breached credential lists at scale and succeed wherever short or trivially guessable passwords are allowed. NIST 800-63B and NIST 800-53 rev5 IA-5(1) mandate a minimum of 8 characters (NIST guidance recommends 12+) with complexity requirements, and AC-7 requires rate-limiting after repeated failed authentication attempts. CWE-521 (Weak Password Requirements) and OWASP A07 both rank this as a systemic authentication failure. Client-only validation is bypassed by any direct API call, so server-side enforcement is non-negotiable.
Severity rationale
High because weak or unrate-limited password endpoints are the direct entry point for automated credential-stuffing and brute-force campaigns targeting every user account.
Remediation
Enforce password complexity and rate-limiting server-side in every password-accepting API route. Client-side validation can improve UX but must never be the sole gate.
// lib/auth-validation.ts
import { z } from 'zod'
export const passwordSchema = z.string()
.min(12, 'Minimum 12 characters')
.regex(/[A-Z]/, 'At least one uppercase letter')
.regex(/[a-z]/, 'At least one lowercase letter')
.regex(/[0-9]/, 'At least one digit')
.regex(/[^A-Za-z0-9]/, 'At least one special character')
Apply rate-limiting at the route level using @upstash/ratelimit or express-rate-limit: no more than 5 password submissions per minute per IP and per user identifier. Validate with Zod before any database interaction — never trust client-supplied values.
Detection
-
ID:
password-requirements -
Severity:
high -
What to look for: Enumerate all password-related endpoints: registration, password reset, and password change flows. For each, quote the validation schema or regex pattern used. Check for minimum length requirement (at least 12 characters per NIST 800-63B), complexity requirements (at least 3 of 4 character types: uppercase, lowercase, numbers, symbols), and rate-limiting on password submission endpoints. Count the rate-limit threshold configured.
-
Pass criteria: Password policy enforces minimum 12 characters, at least 3 of 4 character types (uppercase, lowercase, numbers, symbols), and rate-limiting is present on password submission endpoints with no more than 5 attempts per minute per user/IP. Validation runs server-side (not client-only). Report the ratio of endpoints with validation to total password endpoints.
-
Fail criteria: Passwords allow fewer than 8 characters, no complexity requirements, or no rate-limiting on password endpoints. Do not pass when validation exists only on the client-side with no server-side enforcement.
-
Skip (N/A) when: The project has no user authentication (no login/registration).
-
Detail on fail: Specify which requirements are missing. Example:
"Password minimum length is only 8 chars (need 12+). No complexity requirement enforced. Rate-limiting not found on POST /api/auth/register endpoint." -
Remediation: Implement strong password requirements in your authentication API. Use libraries like
zodorjoifor validation:// lib/auth-validation.ts import { z } from 'zod' const passwordSchema = z.string() .min(12, 'Password must be at least 12 characters') .regex(/[A-Z]/, 'Must include uppercase letter') .regex(/[a-z]/, 'Must include lowercase letter') .regex(/[0-9]/, 'Must include number') .regex(/[!@#$%^&*]/, 'Must include special character') // app/api/auth/register/route.ts import rateLimit from 'express-rate-limit' const limiter = rateLimit({ windowMs: 60 * 1000, max: 5, message: 'Too many password attempts' }) export const POST = limiter(async (req) => { const { password } = await req.json() const result = passwordSchema.safeParse(password) if (!result.success) { return Response.json({ error: 'Invalid password' }, { status: 400 }) } // Continue with registration... })
External references
- nist:rev5 · IA-5(1) — Password-Based Authentication
- nist:rev5 · AC-7 — Unsuccessful Logon Attempts
- fedramp:rev5 · IA-5(1) — FedRAMP IA-5(1) — password complexity and minimum length
- cwe · CWE-521 — Weak Password Requirements
- owasp:2021 · A07 — Identification and Authentication Failures
Taxons
History
- 2026-04-18·v1.0.0·Initial import from gov-fisma-fedramp·automated