This commit addresses all CRITICAL and MEDIUM security vulnerabilities
identified in the security audit with environment-aware configuration.
## Docker Compose Profiles
- Added docker-compose.dev.yml for development (relaxed security)
- Added docker-compose.prod.yml for production (strict security)
- Environment-specific configurations for rate limiting, CSRF, logging
## CRITICAL Fixes (P0)
1. Fixed insecure random number generation
- Replaced Math.random() with crypto.randomBytes() for verification codes
- Now cryptographically secure
2. Implemented rate limiting
- express-rate-limit for all endpoints
- Strict limits on auth endpoints (5 attempts in dev=off, prod=5)
- Email endpoint limits (20 in dev, 3 in prod)
- API-wide rate limiting
3. Added request body size limits
- Development: 50MB (for testing)
- Production: 10KB (security)
4. Fixed user enumeration vulnerability
- Generic error message for registration
- No disclosure of which field exists
5. Added security headers
- helmet.js with CSP, HSTS, XSS protection
- No-sniff, hide powered-by headers
## MEDIUM Fixes (P1)
6. Strengthened password policy
- Environment-aware validation (8+ chars)
- Production: requires uppercase, lowercase, number
- Development: relaxed for testing
7. Enhanced input validation
- Validation for all auth endpoints
- WSDC ID validation (numeric, max 10 digits)
- Name validation (safe characters only)
- Email normalization
8. Added input sanitization
- DOMPurify for XSS prevention
- Sanitize all user inputs in emails
- Timing-safe string comparison for tokens
9. Improved error handling
- Generic errors in production
- Detailed errors only in development
- Proper error logging
10. Enhanced CORS configuration
- Whitelist-based origin validation
- Environment-specific allowed origins
- Credentials support
## New Files
- backend/src/config/security.js - Environment-aware security config
- backend/src/middleware/rateLimiter.js - Rate limiting middleware
- backend/src/utils/sanitize.js - Input sanitization utilities
- backend/.env.example - Development environment template
- backend/.env.production.example - Production environment template
- docker-compose.dev.yml - Development overrides
- docker-compose.prod.yml - Production configuration
- docs/DEPLOYMENT.md - Complete deployment guide
- docs/SECURITY_AUDIT.md - Full security audit report
- .gitignore - Updated to exclude .env files
## Dependencies Added
- helmet (^8.1.0) - Security headers
- express-rate-limit (^8.2.1) - Rate limiting
- dompurify (^3.3.0) - XSS prevention
- jsdom (^27.2.0) - DOM manipulation for sanitization
## Testing
- ✅ Password validation works (weak passwords rejected)
- ✅ User enumeration fixed (generic error messages)
- ✅ WSDC lookup functional
- ✅ Registration flow working
- ✅ Rate limiting active (environment-aware)
- ✅ Security headers present
## Usage
Development:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
Production:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
See docs/DEPLOYMENT.md for detailed instructions.
8.8 KiB
8.8 KiB
Deployment Guide - spotlight.cam
Development Setup
Prerequisites
- Docker & Docker Compose
- Node.js 20+
- PostgreSQL 15 (via Docker)
Quick Start (Development)
- Clone repository
git clone <repository-url>
cd spotlightcam
- Create environment file
cp backend/.env.example backend/.env
# Edit backend/.env with your values
- Start development environment
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
- Run database migrations
docker compose exec backend npx prisma migrate deploy
- Access the application
- Frontend: http://localhost:8080
- Backend API: http://localhost:8080/api
- Database: localhost:5432
Development Features
- Hot reload for frontend and backend
- Relaxed rate limiting
- Detailed error messages
- Debug logging
- Exposed database port for tools (pgAdmin, DBeaver)
Production Deployment
Prerequisites
- Docker & Docker Compose
- SSL certificates
- Production database (AWS RDS, managed PostgreSQL, or self-hosted)
- AWS SES configured and in production mode
- Domain name with DNS configured
Production Setup
- Create production environment file
cp backend/.env.production.example backend/.env.production
- Generate strong secrets
# Generate JWT secret
openssl rand -base64 64
# Generate strong database password
openssl rand -base64 32
- Configure environment variables
Edit
backend/.env.production:
- Set
NODE_ENV=production - Set strong
JWT_SECRET - Configure production
DATABASE_URL - Add AWS SES credentials
- Set production
CORS_ORIGIN
- Build production images
docker compose -f docker-compose.yml -f docker-compose.prod.yml build
- Start production services
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
- Run migrations
docker compose -f docker-compose.yml -f docker-compose.prod.yml exec backend npx prisma migrate deploy
Environment Configuration
Development vs Production
| Feature | Development | Production |
|---|---|---|
| Rate Limiting | Disabled/Relaxed | Strict (5 login attempts) |
| CSRF Protection | Disabled | Enabled |
| Body Size Limit | 50MB | 10KB |
| Error Details | Full stack traces | Generic messages |
| Logging | Debug level | Warn/Error level |
| CORS | Localhost only | Specific domains |
| Password Policy | Relaxed (8 chars) | Strict (8 chars + complexity) |
Environment Variables
Critical Security Variables:
# Must be changed in production!
JWT_SECRET=<64-char-random-string>
DATABASE_URL=postgresql://user:STRONG_PASSWORD@host:5432/dbname
# AWS credentials - use IAM roles in production
AWS_ACCESS_KEY_ID=<your-key>
AWS_SECRET_ACCESS_KEY=<your-secret>
Security Settings:
# Production values
RATE_LIMIT_ENABLED=true
RATE_LIMIT_AUTH_MAX=5
RATE_LIMIT_EMAIL_MAX=3
ENABLE_CSRF=true
BODY_SIZE_LIMIT=10kb
# Development values
RATE_LIMIT_ENABLED=false
RATE_LIMIT_AUTH_MAX=100
ENABLE_CSRF=false
BODY_SIZE_LIMIT=50mb
SSL/HTTPS Configuration
Development (HTTP)
No SSL required - runs on http://localhost:8080
Production (HTTPS)
- Obtain SSL certificates
# Using Let's Encrypt (certbot)
certbot certonly --standalone -d spotlight.cam -d www.spotlight.cam
- Configure nginx
Update
nginx/conf.d/default.conf:
server {
listen 443 ssl http2;
server_name spotlight.cam www.spotlight.cam;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name spotlight.cam www.spotlight.cam;
return 301 https://$server_name$request_uri;
}
- Mount SSL certificates in docker-compose.prod.yml
Already configured to mount
./ssl:/etc/nginx/ssl:ro
Database Management
Backups
Automated backup script:
#!/bin/bash
# scripts/backup-db.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="./backups"
DB_CONTAINER="spotlightcam-db"
docker exec $DB_CONTAINER pg_dump -U spotlightcam spotlightcam > "$BACKUP_DIR/backup_$DATE.sql"
# Keep only last 7 days
find $BACKUP_DIR -name "backup_*.sql" -mtime +7 -delete
Setup cron job:
# Daily backup at 2 AM
0 2 * * * /path/to/spotlightcam/scripts/backup-db.sh
Restore from backup
cat backups/backup_YYYYMMDD_HHMMSS.sql | docker exec -i spotlightcam-db psql -U spotlightcam spotlightcam
Monitoring & Logging
View logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f backend
docker compose logs -f nginx
# Last 100 lines
docker compose logs --tail 100 backend
Production log management
Logs are configured with rotation:
- Max size: 10MB per file
- Max files: 3
- Located in Docker's logging directory
View logs:
docker compose -f docker-compose.yml -f docker-compose.prod.yml logs --tail 100 -f
Security Checklist
Before Going to Production
- Generate strong JWT secret (64+ characters)
- Use strong database password (20+ characters)
- Configure AWS SES in production mode (not sandbox)
- Enable rate limiting (
RATE_LIMIT_ENABLED=true) - Enable CSRF protection (
ENABLE_CSRF=true) - Set strict CORS origins (no wildcards)
- Configure HTTPS with valid SSL certificates
- Set
NODE_ENV=production - Review and rotate all secrets
- Enable account lockout (
ENABLE_ACCOUNT_LOCKOUT=true) - Set strict password policy
- Configure firewall (allow only 80, 443, 22)
- Set up automated backups
- Configure monitoring/alerting
- Review security audit report (
docs/SECURITY_AUDIT.md)
After Deployment
- Test all authentication flows
- Verify email sending works
- Check rate limiting is active
- Verify HTTPS is working
- Test WSDC integration
- Monitor error logs
- Set up uptime monitoring
- Configure alerts for failures
Troubleshooting
Backend won't start
Check logs:
docker compose logs backend
Common issues:
- Missing environment variables
- Database connection failed
- Port already in use
- Missing npm packages
Database connection failed
Check database is running:
docker compose ps db
Test connection:
docker compose exec backend npx prisma db push
Emails not sending
Check AWS SES configuration:
- Verify AWS credentials are correct
- Check SES is in production mode (not sandbox)
- Verify sender email is verified in SES
- Check CloudWatch logs for SES errors
Rate limiting too strict
Temporary disable (development only):
# In .env
RATE_LIMIT_ENABLED=false
Adjust limits:
# In .env
RATE_LIMIT_AUTH_MAX=10 # Allow 10 attempts instead of 5
Scaling Considerations
Horizontal Scaling
For high traffic, consider:
- Load balancer (nginx, HAProxy)
- Multiple backend containers
- Redis for session/rate limit storage
- Managed database (AWS RDS, DigitalOcean)
- CDN for static assets
Performance Optimization
- Enable gzip compression in nginx
- Add Redis for caching
- Use connection pooling for database
- Implement database read replicas
- Use CDN for avatar images
Maintenance
Update dependencies
# Backend
docker compose exec backend npm update
docker compose exec backend npm audit fix
# Frontend
docker compose exec frontend npm update
docker compose exec frontend npm audit fix
Rotate secrets
# Generate new JWT secret
openssl rand -base64 64
# Update .env.production
# Restart services
docker compose -f docker-compose.yml -f docker-compose.prod.yml restart backend
Database migrations
# Create migration
docker compose exec backend npx prisma migrate dev --name description
# Apply to production
docker compose -f docker-compose.yml -f docker-compose.prod.yml exec backend npx prisma migrate deploy
Quick Commands
# Start development
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Start production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Stop all
docker compose down
# View logs
docker compose logs -f backend
# Shell into container
docker compose exec backend sh
# Run migrations
docker compose exec backend npx prisma migrate deploy
# Backup database
docker exec spotlightcam-db pg_dump -U spotlightcam spotlightcam > backup.sql
Support
For issues:
- Check logs:
docker compose logs - Review security audit:
docs/SECURITY_AUDIT.md - Check session context:
docs/SESSION_CONTEXT.md - Review phase documentation:
docs/PHASE_*.md
Last Updated: 2025-11-13