This document outlines security best practices and configurations for the DineInGo application.
What NOT to commit:
.envfiles- API keys
- Database credentials
- JWT secrets
- Firebase service account keys
- SSL certificates
- Private keys
-
Copy the example files:
# Frontend cp .env.example .env # Backend cp backend/.env.example backend/.env
-
Fill in your actual values in the
.envfiles -
Verify .gitignore includes:
.env .env.local backend/.env *-firebase-adminsdk-*.json
-
MONGODB_URI- Database connection string -
EMAIL_USER- Gmail account -
EMAIL_PASS- Gmail app password -
JWT_SECRET- Token signing key -
ADMIN_CODE- Admin access code -
FIREBASE_PRIVATE_KEY- Firebase admin SDK key
-
VITE_GOOGLE_MAPS_API_KEY- Google Maps API -
VITE_MAPBOX_API_KEY- Mapbox API -
VITE_FIREBASE_API_KEY- Firebase client config -
VITE_FIREBASE_*- Other Firebase configs
DO:
- ✅ Store in environment variables
- ✅ Use different keys for dev/staging/production
- ✅ Rotate keys regularly
- ✅ Set up API key restrictions (IP, domain, API)
- ✅ Monitor API usage
DON'T:
- ❌ Hardcode in source code
- ❌ Commit to version control
- ❌ Share in public channels
- ❌ Use production keys in development
MongoDB Atlas:
- Enable IP whitelist
- Use strong passwords (20+ characters)
- Enable database encryption
- Regular backups
- Monitor access logs
Connection String:
# ❌ BAD - Exposed credentials
MONGODB_URI=mongodb+srv://admin:password123@cluster.mongodb.net/
# ✅ GOOD - Use environment variables
MONGODB_URI=mongodb+srv://${DB_USER}:${DB_PASS}@${DB_HOST}/${DB_NAME}JWT Secrets:
- Use strong, random strings (32+ characters)
- Never reuse across environments
- Rotate periodically
Generate secure JWT secret:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"Admin Code:
- Change default admin code immediately
- Use 6+ digit codes
- Store in environment variable
- Consider implementing rate limiting
Gmail App Passwords:
- Enable 2-Factor Authentication
- Generate app-specific passwords
- Don't use your main Gmail password
- Revoke unused app passwords
Setup:
- Go to Google Account → Security
- Enable 2FA
- Generate App Password
- Use in
EMAIL_PASSenvironment variable
Client-Side (Frontend):
- Firebase API keys are safe to expose (they're restricted by domain)
- Set up Firebase Security Rules
- Enable App Check for production
Server-Side (Backend):
- Keep service account JSON files private
- Never commit to Git
- Use environment variables for credentials
Firebase Security Rules Example:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Only authenticated users can read/write their own data
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}Backend CORS Setup:
// ❌ BAD - Allows all origins
app.use(cors({ origin: '*' }));
// ✅ GOOD - Whitelist specific origins
const allowedOrigins = process.env.CORS_ORIGINS?.split(',') || [];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
}));Security Measures:
- Validate file types
- Limit file sizes
- Scan for malware
- Store outside web root
- Use unique filenames
- Implement access controls
Current Implementation:
// backend/uploads/ is gitignored
// Files are validated by type and size
// Unique filenames prevent overwritesDevelopment:
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/dineingo-dev
CORS_ORIGINS=http://localhost:5173Production:
NODE_ENV=production
MONGODB_URI=mongodb+srv://prod-user:strong-password@prod-cluster.mongodb.net/dineingo
CORS_ORIGINS=https://dineingo.com,https://www.dineingo.com- Change all default passwords
- Use production database
- Enable HTTPS/SSL
- Set up firewall rules
- Configure rate limiting
- Enable logging and monitoring
- Set up error tracking (Sentry, etc.)
- Regular security audits
- Keep dependencies updated
- Implement backup strategy
- Go to Google Cloud Console
- Select your project
- Navigate to APIs & Services → Credentials
- Click on your API key
- Set restrictions:
- Application restrictions: HTTP referrers
- Website restrictions: Add your domain
- API restrictions: Only enable required APIs
- Go to Firebase Console
- Project Settings → General
- Add authorized domains
- Set up App Check
- Configure Security Rules
- Failed login attempts
- Unusual API usage
- Database connection failures
- High error rates
- Suspicious file uploads
- Rate limit violations
// ❌ DON'T log sensitive data
console.log('User login:', { email, password }); // BAD!
// ✅ DO log safely
console.log('User login attempt:', { email, timestamp }); // GOOD-
Immediately:
- Revoke compromised keys
- Generate new keys
- Update environment variables
- Deploy updated configuration
-
Investigate:
- Check access logs
- Identify unauthorized usage
- Assess damage
-
Prevent:
- Review security practices
- Update documentation
- Train team members
- All secrets in environment variables
- .env files in .gitignore
- No hardcoded credentials in code
- API keys have restrictions
- Database has IP whitelist
- HTTPS enabled in production
- CORS properly configured
- Rate limiting implemented
- Input validation on all endpoints
- File upload security measures
- Regular dependency updates
- Security headers configured
- Error messages don't leak info
- Logging doesn't expose secrets
- OWASP Top 10
- Node.js Security Best Practices
- MongoDB Security Checklist
- Firebase Security Rules
- Express Security Best Practices
For security concerns or to report vulnerabilities:
- Email: security@dineingo.com
- Do NOT post security issues publicly
- Use responsible disclosure practices