demander IA de faire tous les modifications pour que le webapp soit pret au déploiement.
Force connection HTTPS, proxy-inversé, WSGI de production, reset cookie de conncection à chaque reconnection, limite sur les mdp, fichiers et One on One par minute, verification d'injection de SQL dans les champs d'entrées. renommage des fichiers lors du téléchargement, fichier de backup quotidien pour la bd et j'ai oublié quelque chose :(
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# Team Tryouts - Production Deployment Guide (Windows)
|
||||
|
||||
This document outlines the secure production deployment for the Team Tryouts
|
||||
Flask application on Windows with Nginx reverse proxy.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```
|
||||
Internet → Nginx (HTTPS:443) → Waitress (127.0.0.1:5000) → Flask App
|
||||
```
|
||||
|
||||
- **Nginx**: TLS termination, static file serving, rate limiting, security headers
|
||||
- **Waitress**: Production WSGI server with multiple worker threads
|
||||
- **Flask**: Application logic (never exposed directly to the internet)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Python 3.12+** installed
|
||||
2. **Nginx for Windows** downloaded from [nginx.org](https://nginx.org/en/download.html)
|
||||
3. **SSL Certificate** (Let's Encrypt via certbot or commercial provider)
|
||||
4. **Windows Firewall** configured properly
|
||||
|
||||
## Step 1: Install Dependencies
|
||||
|
||||
```powershell
|
||||
# Install Python packages
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Create required directories
|
||||
mkdir logs
|
||||
mkdir backups
|
||||
```
|
||||
|
||||
## Step 2: Configure Environment Variables
|
||||
|
||||
Create a `.env` file in the project root:
|
||||
|
||||
```env
|
||||
# Security (REQUIRED - generate with: python -c "import secrets; print(secrets.token_hex(32))")
|
||||
SECRET_KEY=<your-generated-64-char-hex-key>
|
||||
|
||||
# Database
|
||||
DATABASE_URL=sqlite:///team_tryouts.db
|
||||
|
||||
# Security settings
|
||||
SESSION_COOKIE_SECURE=true
|
||||
FORCE_HTTPS=true
|
||||
FLASK_DEBUG=false
|
||||
|
||||
# CORS (set to your actual domain in production)
|
||||
CORS_ALLOWED_ORIGINS=https://yourdomain.com
|
||||
|
||||
# Discord bot (optional)
|
||||
DISCORD_BOT_TOKEN=
|
||||
DISCORD_WEBHOOK_URL=
|
||||
|
||||
# Backup settings
|
||||
BACKUP_DIR=./backups
|
||||
BACKUP_RETENTION_DAYS=30
|
||||
```
|
||||
|
||||
**Important**: Never commit `.env` to version control.
|
||||
|
||||
## Step 3: Configure Nginx
|
||||
|
||||
1. Copy `nginx.conf` to your Nginx installation directory (e.g., `C:\nginx\conf\`)
|
||||
2. Place SSL certificate files:
|
||||
- `C:\nginx\certs\fullchain.pem`
|
||||
- `C:\nginx\certs\privkey.pem`
|
||||
3. Start Nginx: `C:\nginx\nginx.exe`
|
||||
|
||||
### Obtaining SSL Certificates
|
||||
|
||||
Using Let's Encrypt with certbot (recommended):
|
||||
|
||||
```powershell
|
||||
# Using certbot on Windows
|
||||
certbot certonly --standalone -d yourdomain.com
|
||||
```
|
||||
|
||||
Or use your hosting provider's SSL certificate.
|
||||
|
||||
## Step 4: Start the Application
|
||||
|
||||
```powershell
|
||||
# Production start
|
||||
python wsgi.py
|
||||
|
||||
# Or with custom port/threads
|
||||
$env:PORT=5000
|
||||
$env:WAITRESS_THREADS=5
|
||||
python wsgi.py
|
||||
```
|
||||
|
||||
## Step 5: Configure Windows Firewall
|
||||
|
||||
```powershell
|
||||
# Allow only necessary ports
|
||||
New-NetFirewallRule -DisplayName "Nginx HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
|
||||
New-NetFirewallRule -DisplayName "Nginx HTTP Redirect" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow
|
||||
|
||||
# Block direct access to Waitress port (5000) from outside
|
||||
New-NetFirewallRule -DisplayName "Block Waitress External" -Direction Inbound -Protocol TCP -LocalPort 5000 -Action Block
|
||||
```
|
||||
|
||||
## Step 6: Set Up Automated Backups
|
||||
|
||||
Create a scheduled task for daily backups:
|
||||
|
||||
```powershell
|
||||
# Run backup script daily at 2:00 AM
|
||||
$Action = New-ScheduledTaskAction -Execute "python" -Argument "backup.py" -WorkingDirectory "C:\path\to\team-tryouts"
|
||||
$Trigger = New-ScheduledTaskTrigger -Daily -At 2:00AM
|
||||
Register-ScheduledTask -TaskName "TeamTryoutsBackup" -Action $Action -Trigger $Trigger
|
||||
```
|
||||
|
||||
## Step 7: Run Security Validation
|
||||
|
||||
Before going live:
|
||||
|
||||
```powershell
|
||||
# Run the security scanner
|
||||
python security_scan.py --url https://yourdomain.com
|
||||
```
|
||||
|
||||
All checks must pass before deployment.
|
||||
|
||||
## Security Checklist
|
||||
|
||||
- [ ] `.env` is not committed to repository
|
||||
- [ ] `SECRET_KEY` is strong (64+ hex characters, randomly generated)
|
||||
- [ ] `FLASK_DEBUG` is set to `false`
|
||||
- [ ] Nginx is running with HTTPS (port 443)
|
||||
- [ ] HTTP (port 80) redirects to HTTPS
|
||||
- [ ] TLS 1.2+ configured (TLS 1.0/1.1 disabled)
|
||||
- [ ] HSTS header is present (`max-age=31536000; includeSubDomains; preload`)
|
||||
- [ ] CSP header is configured with no `unsafe-eval`
|
||||
- [ ] `server_tokens` is `off` in Nginx
|
||||
- [ ] File uploads restricted to PDF only
|
||||
- [ ] File uploads limited to 16MB
|
||||
- [ ] Database backups scheduled daily
|
||||
- [ ] Firewall rules applied (only 80/443 open)
|
||||
- [ ] Application is not running as administrator
|
||||
- [ ] Logs directory exists and is writable
|
||||
- [ ] Health check endpoint returns 200
|
||||
|
||||
## Monitoring
|
||||
|
||||
- **Application logs**: `./logs/app.log`
|
||||
- **Error logs**: `./logs/errors.log`
|
||||
- **Auth logs**: `./logs/auth.log`
|
||||
- **Nginx access logs**: `C:\nginx\logs\access.log`
|
||||
- **Nginx error logs**: `C:\nginx\logs\error.log`
|
||||
|
||||
Monitor these logs regularly for suspicious activity.
|
||||
|
||||
## Maintenance
|
||||
|
||||
- Run `pip-audit` weekly to check for vulnerabilities
|
||||
- Run `python security_scan.py` after any configuration changes
|
||||
- Test backup restoration quarterly
|
||||
- Review and rotate `SECRET_KEY` if compromised
|
||||
- Keep Python and system packages updated
|
||||
@@ -0,0 +1,169 @@
|
||||
# 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**: _______________
|
||||
Reference in New Issue
Block a user