# Pre-Deployment Security Checklist Run through this checklist before deploying to production. ## Phase 1 — Transport Security - [ ] SSL certificate obtained and installed - [ ] All HTTP requests redirect to HTTPS (301) - [ ] HSTS header present: `max-age=31536000; includeSubDomains; preload` - [ ] TLS 1.2 minimum, TLS 1.3 preferred - [ ] Strong ciphers configured (no RC4, 3DES, or export-grade) - [ ] OCSP Stapling configured (optional but recommended) ## Phase 2 — Production WSGI Server - [ ] Application running via Waitress (not Flask dev server) - [ ] Worker threads: `CPU * 2 + 1` - [ ] Application bound to `127.0.0.1` (not `0.0.0.0`) - [ ] Graceful shutdown configured ## Phase 3 — Secure Cookies & Sessions - [ ] `SESSION_COOKIE_SECURE = True` - [ ] `SESSION_COOKIE_HTTPONLY = True` - [ ] `SESSION_COOKIE_SAMESITE = "Lax"` - [ ] Session timeout ≤ 1 hour - [ ] Session regenerated after login - [ ] Session cleared after logout ## Phase 5 — Authentication Security - [ ] Passwords hashed with werkzeug/bcrypt (never plain text) - [ ] Password policy enforced (min 8 chars, uppercase, lowercase, digit) - [ ] Account lockout after 5 failed attempts (15 min) - [ ] CAPTCHA on registration form - [ ] Rate limiting on login (10/min) and registration (3/hr) ## Phase 6 — CSRF Protection - [ ] CSRF protection enabled (Flask-WTF) - [ ] All POST/PUT/PATCH/DELETE requests protected - [ ] CSRF-exempt routes reviewed and justified ## Phase 7 — Input Validation - [ ] All form inputs validated with Marshmallow schemas - [ ] Input whitespace stripped automatically - [ ] Email format validated - [ ] Phone format validated (if provided) - [ ] Discord username format validated (if provided) ## Phase 8 — SQL Injection Protection - [ ] All database queries use SQLAlchemy ORM - [ ] No raw SQL with string interpolation - [ ] Parameterized queries used if raw SQL is necessary ## Phase 9 — HTTP Security Headers - [ ] `X-Content-Type-Options: nosniff` - [ ] `X-Frame-Options: DENY` - [ ] `Referrer-Policy: strict-origin-when-cross-origin` - [ ] `Permissions-Policy: camera=(), microphone=(), geolocation=()` - [ ] `Cross-Origin-Opener-Policy: same-origin` - [ ] `Content-Security-Policy` configured - [ ] CSP does not contain `unsafe-eval` ## Phase 10 — CORS - [ ] CORS configured with explicit allowed origins - [ ] No wildcard (`*`) origin in production - [ ] Only necessary methods exposed - [ ] Credentials support configured properly ## Phase 11 — API Security - [ ] All API endpoints require authentication - [ ] Authorization verified per-endpoint (not just authentication) - [ ] Cross-user data access prevented (e.g., Player A cannot view Player B's data) ## Phase 12 — File Upload Security - [ ] Upload size limited to 16MB (`MAX_CONTENT_LENGTH`) - [ ] File extensions restricted to PDF only - [ ] Files stored with UUID filenames (not original names) - [ ] Upload directory outside web root ## Phase 13 — Logging & Monitoring - [ ] Structured logging configured - [ ] Separate logs for errors and auth events - [ ] Sensitive data filtered from logs - [ ] Log rotation configured - [ ] Logs directory secured ## Phase 14 — Rate Limiting & Abuse Protection - [ ] Global rate limits configured - [ ] Login: 10 requests/minute - [ ] Registration: 3 requests/hour - [ ] CAPTCHA on registration ## Phase 15 — Reverse Proxy Security - [ ] `server_tokens off` in Nginx - [ ] Request size limits configured - [ ] Buffer size limits configured - [ ] Timeout settings configured - [ ] Real IP forwarding headers set ## Phase 16 — Database Security - [ ] Database not accessible from outside - [ ] Least-privilege database user (when using PostgreSQL/MySQL) - [ ] Daily automated backups configured - [ ] Backup restoration tested ## Phase 17 — Dependency Security - [ ] All packages pinned to specific versions - [ ] Dependabot configured for automated updates - [ ] pip-audit run with no critical vulnerabilities - [ ] Regular dependency review schedule ## Phase 18 — Infrastructure - [ ] Firewall: only ports 80 and 443 open - [ ] Block direct access to application port (5000) - [ ] SSH key authentication only (no password) - [ ] Automatic security updates enabled - [ ] Application running with least privilege ## Phase 19 — Flask Best Practices - [ ] DEBUG mode disabled - [ ] Custom error handlers for 400/401/403/404/429/500 - [ ] No stack traces exposed in error pages - [ ] Environment variables for all configuration - [ ] Health check endpoint (`GET /health`) working - [ ] Blueprints used for modular organization ## Phase 20 — Deployment & CI/CD - [ ] Code in version control (Git) - [ ] Main branch protected - [ ] CI pipeline running (lint, security scan, tests) - [ ] No secrets committed to repository - [ ] Backup before each deployment ## Phase 21 — Final Validation - [ ] Run `python security_scan.py --url https://yourdomain.com` - [ ] Scan with Mozilla Observatory: https://observatory.mozilla.org/ - [ ] Scan with SecurityHeaders.com: https://securityheaders.com/ - [ ] Verify all pages redirect correctly to HTTPS - [ ] Check cookies: Secure, HttpOnly, SameSite - [ ] Confirm debug mode is off - [ ] Review initial logs for sensitive data leaks - [ ] Test rate limiting on login and registration - [ ] Test account lockout mechanism - [ ] Test file upload restrictions (non-PDF should fail) --- **Date Validated**: _______________ **Validated By**: _______________ **Notes**: _______________