-
JWT-based Authentication
- HttpOnly cookies prevent XSS attacks
- Secure flag enabled in production (HTTPS only)
- SameSite=strict prevents CSRF attacks
- 8-hour token expiration
-
Password Security
- Passwords hashed with bcryptjs (cost factor: 10)
- Constant-time comparison prevents timing attacks
- Password cleared from memory after use
- Failed login attempts logged
- No user enumeration (same error for invalid email/password)
-
Rate Limiting
- Login attempts: 3 per 3 minutes (production)
- Submission: 3 per 5 minutes (production)
- Automatic IP blocking after threshold
- Configurable per environment
-
Session Management
- Server-side token verification
- Automatic logout after 8 hours
- Cookie cleared on logout
- No session storage in localStorage
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: (comprehensive policy)
Permissions-Policy: camera=(), microphone=(), geolocation=()
- Same-origin checks on sensitive endpoints
- Content-Type validation
- Cloudflare/Vercel IP detection
-
Server-side Validation
- Email format validation
- Password length limits (max 128 chars)
- Message length limits (max 1000 chars)
- Music field limits (max 120 chars)
- HTML/script tag stripping
-
Profanity Filtering
- Configurable word list
- Automatic censoring
-
Bot Detection
- User-agent analysis (isbot library)
- Arcjet DDoS protection
- Rate limiting per IP
-
MongoDB Best Practices
- Connection string in environment variables
- Mongoose schema validation
- Lean queries to prevent prototype pollution
- No direct query string injection
-
Audit Logging
- All admin actions logged
- IP addresses recorded
- Timestamps for all events
- Failed login attempts tracked
-
No User Tracking
- No cookies for public users
- No authentication required for submissions
- IP addresses hashed before storage (optional)
-
Data Minimization
- Only collect necessary fields
- No personal information required
- Music field optional
-
Admin Privacy
- Admin emails not exposed in UI
- Login attempts rate-limited
- Session cookies httpOnly
-
Authentication Required
/admin/*- Server-side token verification/api/admin/*- Cookie-based auth/api/confessions/*(GET/PATCH) - Admin only- POST
/api/confessions- Public (rate-limited)
-
Request Validation
- Content-Type checks
- Method validation
- Parameter sanitization
- Max body size limits
-
Error Handling
- Generic error messages (no stack traces)
- Status codes properly set
- Sensitive info never exposed
- Errors logged server-side only
-
Environment Variables
- All secrets in .env file
- .env excluded from git
- .env.example provided
- No hardcoded credentials
-
Secret Management
- JWT_SECRET: min 32 characters
- ADMIN_SETUP_KEY: rotated after use
- ARCJET_KEY: stored securely
- MONGODB_URI: connection string protected
- MONGODB_DB: database name for this app
- Set NODE_ENV=production
- Generate strong JWT_SECRET (32+ chars)
- Enable secure cookie flag
- Configure MongoDB IP whitelist
- Set up Arcjet DDoS protection
- Enable rate limiting
- Review blocked IPs list
- Rotate ADMIN_SETUP_KEY after initial setup
- Enable HTTPS (required)
- Configure CSP headers
- Set up monitoring/alerts
- Regular dependency updates
- Backup strategy in place
Query audit logs:
// Recent admin logins
db.auditlogs.find({ action: "admin_login" }).sort({ createdAt: -1 }).limit(10);
// Failed login attempts
db.auditlogs.find({ action: "admin_login_failed" }).sort({ createdAt: -1 }).limit(10);
// Suspicious patterns
db.auditlogs.aggregate([
{ $match: { action: "admin_login_failed" } },
{ $group: { _id: "$ip", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);If suspicious activity detected:
- Check audit logs for patterns
- Add IP to BLOCKED_IPS if needed
- Rotate JWT_SECRET
- Force logout all sessions
- Review recent confession submissions
- Check MongoDB access logs
- Update Arcjet rules
- Review audit logs
- Check failed login attempts
- Monitor rate limiting triggers
- Review new confessions
- Update dependencies (npm audit)
- Review security headers
- Check Arcjet dashboard
- Rotate admin passwords
- Database backup verification
- Rotate JWT_SECRET
- Security audit
- Penetration testing (if applicable)
- Update emergency response procedures
- Two-factor authentication (2FA)
- Email notifications on login
- IP geolocation tracking
- Advanced bot detection (hCaptcha)
- Session management UI
- Automated threat response
- Data encryption at rest
- Regular automated security scans
For security issues, please report to the project maintainers immediately. Do not create public GitHub issues for security vulnerabilities.
Last Updated: February 12, 2026 Security Audit Status: ✅ Passed (Self-Audit)