You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Argon2id password hashing - Replaced bcrypt (server-side) and PBKDF2 (client-side) with Argon2id for both. Argon2id is memory-hard and resistant to GPU/ASIC brute-force attacks.
AES-256-GCM encryption - Replaced CryptoJS AES-CBC with Web Crypto API AES-256-GCM (authenticated encryption). Eliminates padding oracle attack surface.
Rate limiting - Added Flask-Limiter (10 requests/minute per IP) on the secret retrieval endpoint to prevent brute-force attacks.
Per-secret lockout - Secrets lock after 10 failed password attempts.
One-time secret race condition fix - Atomic claim pattern prevents concurrent requests from both retrieving a one-time secret. Uses file rename (local), dict lock (memory), head+delete (S3), and generation-match delete (GCS).
Security headers - Added Content-Security-Policy, X-Frame-Options (DENY), X-Content-Type-Options (nosniff), Referrer-Policy (no-referrer), and Permissions-Policy via nginx.
Strict CSP - No 'unsafe-inline' in script-src. All inline scripts and event handlers moved to external JS files. All third-party scripts consolidated to a single CDN (jsdelivr). Inline styles replaced with the hidden HTML attribute where possible.
Input validation - All POST endpoints validate JSON fields, types, and allowed values. Returns 400 on invalid input. Unsupported version values are strictly rejected (400).
ProxyFix hardened - Changed from x_host=1 to x_for=1, x_proto=1, x_host=0 to prevent host header injection.
Nginx body size - Reduced client_max_body_size from 1G to 2m to match application limits.
Config key warning - Startup warning if secret_key appears to be a default or is too short.
PBKDF2 iteration count - Increased client-side PBKDF2-SHA256 key derivation from 210,000 to 600,000 iterations per OWASP recommendations.
Modulo bias fix - Random password generation now uses rejection sampling to eliminate bias.
Password visibility toggle - Password fields default to hidden (type="password") with eye icon toggle on both create and retrieve pages.
HSTS enabled by default in nginx config (2-year max-age, includeSubDomains, preload).
Flask debug mode decoupled from LOG_LEVEL to prevent accidental Werkzeug debugger exposure in containers.