- ✅ JWT tokens for authentication
- ✅ Password hashing (bcrypt with 10 salt rounds)
- ✅ Token expiration (7 days)
- ✅ Protected routes with auth middleware
- ✅ OAuth 2.0 (Google Sign-In, Discord OAuth)
- ✅ Password change requires current password verification
- ✅ OAuth accounts protected from password changes
- ✅ Zod schema validation on all inputs (auth, expenses, user updates, predictions)
- ✅ Request body size limits (1MB)
- ✅ Type checking and sanitization
- ✅ Password strength validation (min 6 chars, uppercase, digit, special character)
- ✅ Email format validation
- ✅ User type enum validation
- ✅ General API: 50 requests/minute per IP
- ✅ Auth endpoints: 5 requests/minute per IP
- ✅ Redis-backed rate limiting for distributed systems
- ✅ Cloudflare Turnstile CAPTCHA on login/signup pages
- ✅ Server-side Turnstile token verification with Cloudflare API
- ✅ CAPTCHA tokens single-use and time-limited
- ✅ Frontend-side CAPTCHA validation with user feedback
- ✅ Helmet.js enabled
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- X-XSS-Protection: 1
- Strict-Transport-Security (HSTS)
- ✅ FIXED: Restricted to specific origins only
- ✅ Credentials allowed only for whitelisted domains
Issue: CORS was set to * allowing any origin
Fix: Whitelist specific origins only
Impact: Prevents CSRF attacks from malicious websites
- Never commit
.envfiles to Git - Use strong, random JWT_SECRET (min 32 characters)
- Keep OAuth secrets confidential
- Use different secrets for dev/production
- Use environment variables for DB credentials
- Enable MongoDB authentication
- Use connection string encryption
- ✅ Min 6 characters (enforced on frontend and backend)
- ✅ Require uppercase letter (A-Z)
- ✅ Require number (0-9)
- ✅ Require special character (@$!%*?&)
- ✅ Passwords hashed with bcrypt (10 salt rounds)
- ✅ Real-time password strength validation on frontend
- ✅ Visual password strength checklist for user feedback
- ✅ Password visibility toggle (Eye/EyeOff icons)
- ✅ Rate limiting enabled (50 req/min general, 5 req/min auth)
- ✅ Input validation on all endpoints with detailed error messages
- ✅ Authentication required for protected routes
- ✅ JWT tokens expire after 7 days
- ✅ User profile updates validate ownership
- ✅ Account deletion requires authentication
- ✅ Expense operations restricted to owner
- ✅ OAuth provider validation on account linking
- ✅ Rate limiting enabled
- ✅ Input validation on all endpoints
- ✅ Authentication required for protected routes
- ✅ JWT tokens expire after 7 days
// Redirect HTTP to HTTPS
if (process.env.NODE_ENV === 'production') {
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
} else {
next();
}
});
}app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true
}
}));// Log suspicious activities
app.use((req, res, next) => {
if (req.path.includes('..') || req.path.includes('passwd')) {
console.warn(`⚠️ Suspicious request from ${req.ip}: ${req.path}`);
}
next();
});npm install express-mongo-sanitize xss-cleanimport mongoSanitize from 'express-mongo-sanitize';
import xss from 'xss-clean';
app.use(mongoSanitize()); // Prevent NoSQL injection
app.use(xss()); // Prevent XSS attacksIf you plan to use cookies:
npm install csurf- ✅ Password change with current password verification
- ✅ Account deletion with confirmation
- ✅ OAuth account protection (no password changes)
- Email verification on signup (TODO)
- Password reset via email (TODO)
- Two-factor authentication (2FA) (TODO)
- Login notification emails (TODO)
- Session management (view active sessions) (TODO)
- Password reset via email
- Two-factor authentication (2FA)
- Login notification emails
- Session management (view active sessions)
// Log important actions
function auditLog(userId, action, details) {
console.log(`[AUDIT] ${new Date().toISOString()} - User ${userId} - ${action} - ${JSON.stringify(details)}`);
// Save to database for compliance
}// Encrypt sensitive data at rest
import crypto from 'crypto';
const algorithm = 'aes-256-cbc';
const key = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
function encrypt(text) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(text);
encrypted = Buffer.concat([encrypted, cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex');
}- Validate file types
- Limit file sizes
- Scan for malware
- Store files outside web root
- Use random filenames
# Check for vulnerable dependencies
npm audit
# Fix vulnerabilities
npm audit fix- Web application security scanner
- https://www.zaproxy.org/
- Test API endpoints with invalid inputs
- Test authentication bypass attempts
- Test rate limiting
- Chrome Lighthouse (Security audit)
- Check for mixed content warnings
- Verify HTTPS certificate
| Attack Type | Protection | Status |
|---|---|---|
| SQL/NoSQL Injection | Input validation, sanitization | ✅ Zod validation + Mongoose |
| XSS (Cross-Site Scripting) | Input sanitization, CSP headers | |
| CSRF (Cross-Site Request Forgery) | CSRF tokens, SameSite cookies | ✅ CORS restricted |
| Brute Force | Rate limiting, CAPTCHA | ✅ Turnstile + Rate limiting |
| DDoS | Rate limiting, CDN, WAF | ✅ Redis rate limiting |
| Man-in-the-Middle | HTTPS, HSTS | |
| Session Hijacking | Secure cookies, token expiry | ✅ JWT expiry (7d) |
| Credential Stuffing | Rate limiting, CAPTCHA, 2FA | ✅ Turnstile CAPTCHA |
| Password Cracking | Strong password policy, bcrypt | ✅ Regex validation + bcrypt |
| OAuth Token Theft | Secure token handling, HTTPS | ✅ Backend verification |
| Account Takeover | Password verification for changes | ✅ Current password required |
| Man-in-the-Middle | HTTPS, HSTS | |
| Session Hijacking | Secure cookies, token expiry | ✅ JWT expiry |
| Credential Stuffing | Rate limiting, CAPTCHA, 2FA | ✅ CAPTCHA enabled |
Backend (.env)
# Database
MONGO_URI=mongodb+srv://...
# Authentication
JWT_SECRET=<64-character-random-string>
JWT_EXPIRES_IN=7d
# OAuth
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
DISCORD_CLIENT_ID=...
DISCORD_CLIENT_SECRET=...
# Turnstile CAPTCHA
TURNSTILE_SECRET_KEY=...
# Redis
REDIS_HOST=...
REDIS_PORT=...
REDIS_USERNAME=...
REDIS_PASSWORD=...
# CORS
CORS_ORIGIN=http://localhost:5173
# Other
NODE_ENV=development
PORT=5000
ML_API_URL=http://localhost:8000Frontend (.env)
VITE_API_TARGET=http://localhost:5000
VITE_ML_API_URL=http://localhost:8000
VITE_GOOGLE_CLIENT_ID=...
VITE_DISCORD_CLIENT_ID=...
VITE_DISCORD_REDIRECT_URI=...
VITE_TURNSTILE_SITE_KEY=...# Generate JWT secret
### GDPR Compliance (if serving EU users)
- [ ] Privacy policy page
- [ ] Cookie consent banner
- [ ] User data export feature
- ✅ Account deletion feature (DELETE /api/user/profile/delete)
- [ ] Data retention policy
- ✅ Encrypted password storage (bcrypt)
### GDPR Compliance (if serving EU users)
- [ ] Privacy policy page
- [ ] Cookie consent banner
- [ ] User data export feature
- [ ] Account deletion feature
- [ ] Data retention policy
- [ ] Encrypted data storage
### Best Practices
- Only collect necessary data
- Hash/encrypt sensitive data
- Regular security audits
- Incident response plan
- User notification on breaches
---
## 🚨 Security Incident Response Plan
### If Security Breach Occurs:
1. **Immediate Actions**
- Identify and stop the attack
- Change all secrets and passwords
- Revoke all active JWT tokens
- Enable maintenance mode if needed
2. **Investigation**
- Check logs for unauthorized access
- Identify compromised data
- Determine attack vector
3. **Communication**
- Notify affected users
- Report to authorities if required
- Update security measures
4. **Recovery**
- Patch vulnerabilities
- Restore from clean backups
- Monitor for continued attacks
---
## 📚 Additional Resources
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
- [JWT Security Best Practices](https://tools.ietf.org/html/rfc8725)
---
## ✅ Quick Security Audit Checklist
Run this before deploying:
```bash
# Check for vulnerabilities
npm audit
# Check for secrets in code
git secrets --scan
# Test authentication
# - Try accessing protected routes without token
# - Try with expired token
# - Try with invalid token
# Test rate limiting
# - Send 100 requests quickly
# - Verify 429 Too Many Requests response
# Test input validation
# - Send malformed JSON
# - Send SQL injection strings
# - Send XSS payloads
# Test CORS
# - Try requests from unauthorized origin
# - Verify credentials blocked for wrong origin-
OAuth 2.0 Integration
- Google Sign-In with backend token verification
- Discord OAuth with secure callback handling
- Automatic account linking with existing emails
- OAuth provider validation to prevent account hijacking
-
Enhanced Password Security
- Real-time password strength validation with visual feedback
- Password visibility toggle in all password fields
- Current password verification required for password changes
- OAuth accounts protected from password change attempts
- Pre-save hook prevents double hashing
-
Cloudflare Turnstile CAPTCHA
- CAPTCHA required on login and signup forms
- Server-side verification with Cloudflare API
- User-friendly error handling and retry mechanism
-
Profile Management Enhancements
- Comprehensive profile editing (name, email, password)
- Account deletion with confirmation dialog
- Budget and user type configuration
- Conditional UI rendering based on auth provider
-
User Experience Improvements
- Server health checks with auto-retry (30s backend, 45s ML server)
- Loading states during CAPTCHA verification
- Toast notifications for all security-related actions
- Password requirements checklist on signup and profile update
- Password field always excluded from user queries (select: false)
- OAuth provider stored and validated on all operations
- Email uniqueness enforced across all auth methods
- Current password verification prevents unauthorized changes
- Account deletion cascades to remove all user data
Last Updated: December 9, 2025 Security Contact: sumeetdutta040@gmail.com