Files
team-tryouts/docs/security-checklist.md
T
cedrick2711 820cccb25e
CI - Security, Lint & Tests / validate (push) Failing after 1m15s
changement vers google drive storage pour les contrats.
Tentative d'obtenir un token de connection échoue
2026-08-26 20:52:40 -04:00

170 lines
5.5 KiB
Markdown

# 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
- [ ] File content validated by parsing with pypdf (`PdfReader`) — header (`%PDF-`) + at least one parseable page
- [ ] Files stored with UUID filenames (not original names)
- [ ] Upload directory outside web root (or Google Drive in production)
## 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**: _______________